designing model in MVVM and WPF and state management - wpf

In my WPF app, I am using MVVM. I am reading from an XML file, deserialize it to an object model and keeping it in memory.
XML File->BusinessObjectModel(Model)->ViewModel
Whenever the viewmodel needs the model I will provide it from the memory.My problem is when I use the model elements in the views it is updating the model in memory(obviously!). I dont want to do that, I want the model updated only when the user clicks OK in the view(or dialog). How is it usually achieved? Should I only provide the viewmodel a clone of the model and not the original reference?

Editing a clone of the model object would solve the problem, as you suggested.
Another approach would be to have the property bindings use an UpdateSourceTrigger of Explicit. Upon clicking Save, you would programmaticcally call UpdateSource on each binding expression. This requires some extra code, which would belong in the View's code-behind since it is code that manipulates UI elements.
Also consider having a property on your VM for each property exposed in the View, where the backing field of the VM property is not the wrapped Model object's corresponding property. When the user clicks Save, you could then assign each property from the VM to the Model object. Naturally the controls in the View would be bound to the VM properties, not the Model properties. This is effectively like having a clone, without the extra baggage of supporting cloning in the Model layer.
I'm not suggesting that any of these options are better or worse. It all depends on the context in which they are used.

Related

WPF ViewModel not active presenter

There is a ViewModel that consists of some related object (nodes and lines( ,
How it can be possible to display (synchronize) these VM in View and keep object connections.
I use some DataTemplate to map model to view but each object would be synchronized (with powerful binding) to its related object but how can i link (and synchronize) this DataTemplate generated UI element together.
I describe problem from another viewpoint here:
Sunchronizing view model and view
To keep your view synchronized you should use bindings, your binding sources need to implement certain interfaces or be dependency properties though. For collections you need to implement INotifyCollectionChanged and for properties you'd use INotifyPropertyChanged, if you then change the source your view will change as well.
Next to implementing INotifyPropertyChanged and using ICollectionChanged (ObservableCollection) and binding to the views, you might consider implementing IEditableObject when you want to support the editing of the data.
This interface allows you to undo edit actions. Without implementing IEditableObject you would need to go back to the data source to reset the to the original values when canceling the modifications. The interface is also supported by the DataGrid.
You can synchronize the VM and View using Relaying Command Logic.
you can see a sample workout here
Binding the "WindowState" property of a window in WPF using MVVM

WPF/MVVM - should view-models stay constant and just the model change?

I'm a bit in doubt as to what is 'the right way'.
I have an application with concepts like visual studio, so I'll use that to explain:
I have a 'solution' view model and a model behind. The view model is displayed in a 'explorer'.
I can change between the situations where 'no solution is loaded' to 'a solution is loaded' and back.
And finally my question :-) :
Should I keep my view model object and let it reflect that I have a new 'solution object' loaded? Or should I create a new view model object and let the view bind to the new object?
Your Viewmodel contains the state of any data associated with the UI which is not further back in the Model.
One way I answer questions such as yours is by considering what behaviour I want in the UI and what needs binding to some state information. Or, to put it a different way, any time that I feel like writing some code that would cause UI elements to be shown or hidden, think about how that maps to a boolean variable.
So, take large chunks of the UI that only are visible when you have a Model loaded. These might have their visibility bound to a boolean property in the Viewmodel IsSolutionLoaded.
Maybe you want to disable some things if processing is occurring, you could have a property IsCompiling. I've used this approach with a property NotRunningthreadedProcessing as shown below, that let me disable controls when a synchronisation object existed in the Viewmodel.
CNTL_WhiteLevel.SetBinding(ProgressBar.IsEnabledProperty,
new Binding("NotRunningThreadedProcessing"));
// and the C++/CLI property concerned
property bool NotRunningThreadedProcessing {
bool get()
{
return mThreadedCommandSyncher == nullptr;
}
};
What is the arrengement of the ViewModel?
In General
View Model is the localized version of actualmodel and View is updated whenever there is a change i its viewModel through DataBiding.
in your case ,you have 2 states.
1- Your View is Loaded
2- Your View is not loaded
so should I create a new view model object and let the view bind to the new object?
in my thoughts ,YES

Should a ViewModel in MVVM reference the View?

In the MVVM (Model-View-ViewModel) pattern should the ViewModel reference the view. I would think that it should not. But how should the following scenario be handeled? I have a view that has a tab control as the main container, the viewmodel for this view implements a command to add a new tab to the tab control. The easy way would be to allow the viewmodel to reference the view and then in the command implementation to just programmatically add the new tab to the tabcontrol in the view. This just seems wrong. Should I somehow bind the tabcontrol to the viewmodel and then implement a data/control-template to add the new tabs. I hope this makes some kind of sense to somebody :)
In "pure" MVVM, the ViewModel shouldn't really reference the View. It's often convenient, however, to provide some form of interface in the View whereby the ViewModel can interact with it.
However, I've found that I almost never do that anymore. The alternative approach is to use some form of attached property or blend behavior within your View, and bind it to your ViewModel properties. This allows you to keep the View logic 100% within the View. In addition, by creating a behavior for this, you create a reusable type that can be used to handle this in every ViewModel->View interaction. I strongly prefer this approach over having any View logic within the ViewModel.
In order to demonstrate this technique, I wrote a sample for the Expression Code Gallery called WindowCloseBehavior. It demonstrates how you can use a Behavior within the View bound to properties in the ViewModel to handle controlling a Window's life-cycle, including preventing it from being closed, etc.
Reed and Dan covered the general approach but in reference to your specific case, TabControl is an ItemsControl and so can bind its ItemsSource to a data collection in your ViewModel representing the set of tabs to display. The UI for each type of tab can then be represented by a DataTemplate specific to the data type of an item (either using DataType or a DataTemplateSelector). You can then add or remove data items as needed from your VM and have the tabs update automatically without the VM knowing anything about the TabControl.
I find that it's often a helpful compromise to expose an interface on the View that handles View-specific functionality. This is a good way to handle things that are awkward to accomplish with pure binding, such as instructing the form to close, opening a file dialog (though this often gets put in its own service interface) or interacting with controls not designed well for data binding (such as the example you provided.)
Using an interface still keeps the View and ViewModel largely decoupled and enables you to mock the specific IView during testing.
One of us is missing something obvious. Your tab control is an ItemsControl. You should bind the ItemsSource of your tab control to an ovservable collection in your view model. When you handle the command in your view model to add a tab, you simply add a new element to this collection and, voila, you've added a new tab to the control.

MVVM where does the code to load the data belong?

As I wrap my head around the mvvm thing, the view is the view, and the viewmodel is 'a modal of a view' and the model are the entities we are dealing with (or at least that is my understanding). But I'm unclear as to what and when the model entities are populated. So for example:
Lets say I have app that needs to create a new record in a DB. And that record should have default values to start with. Who is responsible for the new record, and getting the default values. Does this have anything to do with MVVM or is that part of a data access layer? Who calls the the viewmodel?
Or for existing records when\where are the records retrieved? And saved if altered?
Thanks
In an overly simplified answer, your ViewModel should contain the LOGIC for controlling what your View displays, as well as how it is allowed to interact with the Model or Data.
Events like Getting data, Saving and Deleting are intercepted through a Command mechanism and pushed into the ViewModel, where they can be tested. Handling 'Dirty' events are also the duty of the ViewModel. As for who Calls the ViewModel, you are entrusting the Calling to the Binding mechanisms available within WPF and Silverlight.
Within the ViewModel it is still about staying with best practices and ensuring that you have a DataAccess layer abstracting your Data Source and possibly using the Repository pattern to abstract that.
The life cycle of a ViewModel could be as simple as the following...
Constructor called by View
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
However since you will probably have a lot of moving parts within the Ctor of the VM, including the Data Repositories Interface you will probably want to work with an IoC. This will make the life cycle of the ViewModel closer to...
View/ViewModel (Depends if you are View or ViewModel first) is pulled out of the IoC
IoC Handles the pairing of the View-ViewModel (Convention based)
Data Repository is Injected into the ViewModel
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
This may seem like more steps, however with an IoC container you are really just calling a single method like IoC.Get(), and the rest of the steps are wired up automatically based on the conventions applied.
I use view-models to control loading (with defaults) and saving my models, and to create collections and objects that I use to bind to my views. This includes setting default values on my models.
State and Bahavior of your view is define in your viewmodel which means all events are declared here.
Who calls the the viewmodel?
it depends who needs it. you can call it in your view.
for existing records when\where are the records retrieved? And saved if altered?
saving and retrieving part is in your viewmodel.
For detailed explanation, visit this site.

Silverlight MVVM linking model and view model

There are lots of great examples around on MVVM but I'm still confused.
Lets say you have a CustomerModel and a CustomerViewModel. It seems there would be a Name property on the CustomerModel and one on the CustomerViewModel. The setter on the CustomerViewModel will set the CustomerModel Name property and then call the OnPropertyChanged(PropName) so that the UI will update. Is this really right? Seems like the getter/setters will be defined twice. If you have a model with 50 properties then thats going to get real tedious.
Also, lets say I set a Qty property. The ViewModel updates the Model. The Model updates its Value property based on the new Qty. How does the ViewModel get notified that the Model property changed?
Your ViewModel doesn't have to encapsulate the Model that strictly. In your scenario, the CustomerViewModel might have a Customer property, which in the end means your View binds to the Model properties... it just does so through the ViewModel. That's perfectly legitimate. That said, however, there's often a benefit to encapsulating this. Your business model may not include change notification. You may not want the user interaction to modify the business model until the user clicks an OK button. Your business model may through exceptions for bad input, while you want to use another form of validation. I'm sure you can think of other things. In fact, I'd guess that most of the time you're going to want the encapsulation, so it's not really "tedious" in the sense of just writing a lot of pointless relay methods.
In the customer example that you give, the CustomerModel contains all the information that is stored by your database (or other backend). The CustomerViewModel contains similar information if it's going to be shown on the UI (Name etc., potentially 50 other properties if you have a large class) but as uses the INotifyPropertyChanged interface to show them as properties that the View (i.e. the XAML) can bind to.
e.g.
public int Name
{
get
{
return this.name;
}
set
{
if (this.name!= value)
{
this.name= value;
this.OnPropertyChanged("Name");
}
}
}
The ViewModel also contains other bits of UI state - Visibility flags, current Tab index, more complex bits of text built out of data in several fields, ObservableCollection<> of child items, etc. All are there to be bound to the XAML.
I have seen the ViewModel created from the Model as a one-time, one-way process, e.g. with a constructor:
CustomerViewModel viewModel = new CustomerViewModel(customer);
or as an extension method
CustomerViewModel viewModel = customer.ToViewModel();
I haven't seen any provision for updating a ViewModel for changes to the Model - the point of the ViewModel is that it's isolated from the model. It keeps a separate copy of the data. It does not propagate changes back to the model, not until you press a "save" button. So if you cancel instead, nothing in the model has changed and there's nothing to undo.
You may be trying too hard to keep the ViewModel up to date with the Model - most cases like save or load you can just throw away the current ViewModel and make a new one from the current state of the model. Do you need to keep the ViewModel's UI state and change the data in it? It's not a common requirement but it could be done with a method or two called when the save or load happens.
So there's also the assumption that this wire-up logic happens somewhere. This is why most patterns that involve views also involve controllers that are responsible for acting on commands (e.g. show a customer, save a customer) and setting up new UI state afterwards.
Exactly how this is done, will depend in part on your business model as wekempf has already stated.
Depending on how your displaying Customer info in your UI, you might have an ObservableCollection of Customer(your model) types in your ViewModel. If, for example, you're displaying a master/detail scenario, where you might have a list of customers and show details below when a particular customer is selected.

Resources