MVVM Modelview to View - wpf

As far as i understand ViewModel communicates with View via databinding. But how can one create in ViewModel UIElements for View.
Thanks.

The ViewModel should not create any UIElements directly because the ViewModel should not depend on the View. The ViewModel provides data that the View (i.e. the UIElements) can bind against.
If your question is geared toward how to bootstrap a View, there are two approaches: View-first and ViewModel-first. In the former you create the View first and then create and bind against the ViewModel. In the latter you make the ViewModel create the View (through interfaces). Read more about it here.
If your question is geared toward composing the view of UIElements, this is done through DataBinding and the use of DataTemplates and ControlTemplates.

MVVM is a loose design pattern, it is accectable to put code in the code behind as long as it purely concerned with the UI only, just keep in mind that it may be harder to unit test.
And strictly speaking the ViewModel does not communicate to the View, there is no reference to the View in the ViewModel, rather the View reads data from the ViewModel and executes commands on the ViewModel.

The problem is dynamic component creation needs as I see.
You can put a Container object on a view then on modelView create UIElements and Bind this UIElement collection to Container's Content Property. But I think its not a good practice. This approach breaks Model and View seperation.So you need to avoid of dynamic component creation.
MVVM approach is a bit diffrent. Sometimes force us using tricks. i.e. Instead of using ListBox's MemberPath property you define a ItemTemplate and put ButtonBase elements on the template for supporting Commanding! Or you Extend ListBox and Support Commanding.
My offer instead of dynamic object creation. Use DataTemplates and change the binded members on ModelView,then the view will be automatically created for you.For complex senario's it could be hard. We do them all for the sake of keeping MVVM structure.

Related

Can we create UI Element in ViewModel?

I have some confused about create ui element in viewmodel ? If yes then how can it possible ?
Thank's in advance.
No, in the mvvm pattern the viewmodel is only responsible for providing data and state.
You can theoretically have many views connected to the same viewmodel; A wpf-view for graphics displays and a command-line for text-mode for instance. If you think like that it makes sense where to put which functionality.
If you want to create UI objects programatically, you do that in the views code-behind. You are absolutely allowed to do it there and hook into any events just as you would have in a traditional forms project.
Why do you want to do that? Do you need to generate a dynamic UI at runtime?
The ViewModel isn't for UI elements, though it can hold backing data elements for the UI element (like list of items for a combo box).
UI is a job for the View. You can generate XAML at runtime, but I would not create it "in ViewModel" I would create a separate, distinct presenter or controller class, or use XAML code behind logic. You can reflect over the ViewModel to generate XAML, but I would limit the ViewModel to data and mediation between the View and the Model and keep all UI separate.
I am not a WPF expert, I'm just answering from the general best-practices perspective of MVC/MVVM and the purpose of the ViewModel. Theoretically, your ViewModel should be reusable across multiple UI presentation layers (ASP.NET/Razor/XAML) so avoid UI specific markup in the ViewModel. Limit it to properties, containers, methods, data access calls or service calls, etc.

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.

Matching implementations to parts of the pattern

While trying to understand the MVVM pattern I came across this video linked from the MVVM Light Toolkit website.
In TechDays 2010 - Laurent Bugnion states the WPF/Silverlight both use MVVM pattern for their structure. Can someone please clarify which components in WPF/SL (which Bugnion named specifically and are listed below) are the Model, ViewModel, and View?
These are the three items he stated as being a part of the MVVM pattern:
Code
Dependency Properties
Control Templates (Data Templates?)
I am the first to admit that this is a little bit stretched ;) but let me clarify. The statement was made to illustrate that MVVM is a very natural pattern in SL/WPF (and all other frameworks that use XAML and databinding). In the example, I was talking about the separation of concerns between the control's code (not referring to "code" in general, but specifically to a control's code, for example a Button class) and its template. In this illustration, the code acts like a ViewModel, i.e. it drives the view. The template is more obviously the View. And the glue between those is the databinding which is enabled through Dependency Properties.
When I say it is a bit of a stretch, we can see that there is no Model in this analogy. Also, the mechanism binding a control's view to its viewmodel (code) is a little more complex than just DPs and bindings. There are also naming conventions added to that.
In retrospect, I guess I could have been clearer, and I pushed this analogy a bit too far. I guess the main point I would like you to take from this is: In SL/WPF, code and view are loosely coupled through databinding. This is true for basic controls, and you can also structure your application in a loosely coupled manner, with the help of databindings.
I hope it makes a little more sense now ;)
Cheers,
Laurent
I haven't watched the video. Definitely the control templates and data templates are your views. The dependency properties are really also part of your view, but can be bound to data in a class which serves as a model for the view, i.e. the view-model. The "code" he's referring to must be the business logic which is your model.
I would think of it as three objects. You have a view object, like a TextBox control which has styling applied to it in the form of other view objects that comprise the templates. The TextBox also has dependency properties which are objects that can bind (synchronize) a value on the TextBox to a value on another object. That object is the DataContext of the TextBox, which is your view-model object. The view-model object can be thought of as an adapter for a model to support the specific needs of the view.
The Model represents the data and business logic. It should represent your business
(domain) and it should not be aware by anyway of your UI.
The View this is the UI – the bridge between your software and its users. Normally
the View is only aware of the ViewModel but there might be cases in which it may make
sense to expose the Model directly to it. So your XAML for UI like Grid, Button,
DataTemplate,Style, control Template etc can be found here.
The ViewModel: this is the way you connect your model to a specific View. See it has
code that massages your Models in a way that the View can consume. The ViewModel should be
View agnostic as the Model should. So the communication between View and ViewModel is
purely based on DataBinding. When you are dealing with MVVM pattern the use Dependency
property will be bare minimum. for example when you are creating any Custom control at
that time you have to use the Dependency property for the supporting the binding.
three items he stated as being a part of the MVVM pattern
There is a flaw in this. These things are not parts of MVVM; they enable MVVM. Parts of MVVM are Model, View and ViewModel. To call 'code' a part of MVVM or to call it a part of the ViewModel is oversimplifying and useless.
There is code in the Listbox control; it wouldn't function if there weren't.
Of course, code in the View is frowned upon while others say it is very well possible.
When trying to understand MVVM focus on the responsibilities of the Model, ViewModel and View and do not worry too much about code, dependency properties and Control Templates. You cannot map these to MVVM.

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