WPF ViewModel not active presenter - wpf

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

Related

TabControl and MVVM

I am having difficulties in making TabControl run flawlessly in MVVM architecture. Currently what I am doing is having TabControl's ItemsSource property bound to ObservableCollection Screens property. Each time I want to add new tab, I create adequate ViewModel, add it to Screens, and throuh data templates adequate View will be shown.
Problems:
1) it seems that desctructor for my ViewModels are not fired until complete application closes. I am not sure if Data templates are the cause of this. When I remove ViewModel from Screens collection, it should be available for GC, since all I did was added it to Screens collection, which showed the View, and then when command to close the view was issued, I removed from collection. After that I tried to force Gc.Collect, but still dctor fires only on application close. I am not sure why is this happening...
1) in some data structures it is not possible to bind to ViewModel's property through ElementName, so one way around is to use RelativeSource binding. However, this creates lots of binding exceptions when element (ex View) is being closed. Similar problem to mine is described here:
How to avoid Binding Error when parent is removed
In my case TargetNullValue and FallbackValue do not help, and the only way around I have found is to have ViewModel as StaticResource. Problem with this approach is that when using Screens collection and data templates to connect Views and ViewModels, you cannot create viewmodels the usual way:
<UserControl.Resources>
<vm:SomeViewModel x:Key="someViewModel" />
</UserCpntrol.Resources>
So, is there an alternative approach to using TabControl in MVVM scenario, or I am doing something wrong here?
Regarding the destructor part, should not use the destructor. It is the recommended approach to implement the IDisposable interface instead. This will help you to automate the cleanupd of your objects and lets the GC do the dirty work for you:
Use this method to close or release unmanaged resources such as files,
streams, and handles held by an instance of the class that implements
this interface. By convention, this method is used for all tasks
associated with freeing resources held by an object, or preparing an
object for reuse.
My favorite MVVM tutorial uses a Tabcontrol as a central UI control: WPF Apps With The Model-View-ViewModel Design Pattern. This may give you hints to a nice and working approach.

How to make a contained control in a view to do operation by ViewModel triger?

I have a view that containing a user control.
I want to make the view model to notify the user control to do some action (refresh its' data).
I can pace some bool property in my VM and bind it to the user control so it will trigger it, but I think it's a little abuse of the property.
I feel I missing something, and can't find a solution. I will appreciate any comment.
My solution:
I'm going to solve the problem by registering an event of collection changed in my UserControl, since I'm binding to that control a view of a collection thru CollectionViewSource.
My original problem was how to make a chart control inside the UserControl to get updated when I filtering the data source. After the filtering operation from the VM, an event will raise and I will make the chart to get refresh either in the UserContol's code behind
Since you've indicated MVVM tag solution would be pretty straightforward - just bind control to a data by exposing data items/whatever by ViewModel so any data updates would be automatically dispatched to View via bndings if you would provide INotifyPropertyChanged / INotifyCollectionChanged by a ViewModel.
If you've bound your UserControl correctly, you shouldn't need to manually refresh the data since WPF will automatically update the UI when INotifiyPropertyChanged triggers
That said, if you wish to send a message from the ViewModel to the View, I usually use an messaging system of some kind to keep the Views and ViewModels separate. The two I've used and would recommend are MVVM Light's Messenger, or Microsoft Prism's EventAggregator
Either system will allow your ViewModel to broadcast a message, and your View can subscribe to receive these messages and handle them as needed.

designing model in MVVM and WPF and state management

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.

Models, Views, View Models and Presenters

I'm trying to get to grips with different patterns (MVP, MVVM etc) and find one that suits my needs. After all my reading I'm still not sure. Hopefully someone can shed some light on this for me.
At the moment I have a WPF View which implements an interface ICustomView. This interface is injected into my Presenter. The presenter then is responsible for subscribing to data, managing subscriptions etc. When the data is returned to the Presenter it calls various methods against the Model (an IObservable collection of CustomBusinessObjects). It does this using the interface ICustomView since the IObservable is a property of the Model.
The problem I see with this is the Model is too coupled with the View. Also the Presenter is deciding which methods to call against the Model. At the moment the View consists of a WinForms grid and this is exposed by the ICustomView allowing the Presenter to call methods against the View. However it adds to the coupling of Presenter and View which makes it difficult to swap out this WinForms grid for a WPF grid or chart etc
I am considering making the Model an entirely seperate entity lets say IModel with a single method ProcessUpdate(string topic, IMessage payload). This would move logic away from the presenter into the Model. It would also mean more than one view could share the same model. The custom model could have additional interfaces for specific customisations but the Presenter would only need to know about IModel.
Does this sound like a reasonable idea? Am I missing something here?
Any advice appreciated.
Thanks
I would recommend switching from MVP to MVVM because you are using WPF. I would only use MVP if you were using ASP.Net or WinForms.
That being said, your MVVM objects would be:
Model: Simple data object. It should not contain any functionality such as Save or Edit, but can have Validation logic.
View: Your UI. I usually do mine as a DataTemplate for the ViewModel class type. It should bind to your ViewModel's Properties and Commands.
ViewModel: The piece that combines the two. Any data displayed in the View should bind to a property in the ViewModel. Any commands in your View such as Button Clicks should also point to methods in the ViewModel.
For example, when a user hits a GetCustomer button on the View, the ViewModel should receive the command, go and get the CustomerModel, and expose it's Properties for the View to bind to. When the user hits Save the ViewModel should validate that the Model is valid, and then execute the Save code using its CustomerModel property.
Personally, when using WPF I prefer to use a WPF datagrid, and bind it to a datacontext in the MVVM pattern. I think the first thing you need to get rid of is the WinForms grid (it will be almost impossible to decouple your model/view as long as you are using a WinForms grid.
I would do research on a few different things.
The MVVM pattern
WPF DataGrid
Binding the DataGrid to a DataContext
Once you get to that point, all you will need to do is update your datacontext, and your view will update with it.

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.

Resources