Following is excrept from this article on MVVM. Can someone provide example of how these other patterns (command, DI) are used in WPF? Are there any other desgin patterns that are used in WPF that you don't see listed here ?
There are other patterns you should be aware of to assist you in MVVM. Patterns like commanding (baked into WPF, solutions for SL), mediator and gasp dependency injection. .
I've written the article about some of them: WPF and Silverlight design patterns
Here is a brief description of the patterns:
1) MVVM - used as a model converter and as a replacement of the code-behind. Improves testability, it is much easier to write unit tests for ViewModel.
2) Dependency Injection - used for improving testability of a class (you can write unit tests for a specific class separately from others) and for the possibility to change implementation in easier way (change a logger, cache provider, web service etc)
3) Command - can be applied to Button and MenuItem controls by default, disables controls if an action can't be executed. Also used in MVVM pattern as a replacement of code-behind events.
Other patterns from the classic book which are already used in WPF:
Singleton. The Application class in WPF and the HttpContext class
in Web forms.
Adapter. The data-binding engine, which uses the IValueConverter
interface to convert binding values for the UI.
Decorator. The Border class, which decorates any UIElement class
with a border of variable thickness and color.
Façade. The PrintDialog class, which provides a simple interface
that enables you to use the entire printing and document subsystem
that WPF provides.
Command. The ICommand interface, which is implemented by the
RoutedCommand and RoutedUICommand classes.
Iterator. The IEnumerator interface, which many collections and lists
in the .NET Framework implement.
Observer. The INotifyPropertyChanged interface and events.
Data binding (between View and ViewModel) uses the Observer pattern. Also: the Factory pattern can be used to instantiate the ViewModel but that is optional.
Setter dependency injection:
When using MVVM you have to inject an instance of ViewModel into the View by setting it to the view.DataContext property:
var viewModel = new CustomViewModel();
var view = new CustomView();
view.DataContext = viewModel;
Related
I need to send notification from ViewModel to View in MVVM WPF application. In most cases it will be simple MessageBox on View side. Is it unacceptable violation of MVVM pattern to use types like System.Windows.MessageBoxResult or System.Windows.MessageBoxImage in ViewModel (in this case VM must reference UI-specific libraries)?
I need to pass title, message and notification type from VM and by creating custom enumerations I am in fact copying existing functionality from .NET Framework.
You don't need notification mechanism. That's one option. Another is using simple service class:
public class ViewModel
{
IDialogService _dialogService; //ctor injection or use service locator
public void CommandExecute()
{
_dialogService.ShowMessageBox(...);
}
}
public interface IDialogService
{
bool? ShowMessageBox(params....);
}
public class DialogService : IDialogService
{
public bool? ShowDialog(params...)
{
MessageBox.Show(params...);
}
}
I find this approach more straightforward, easier to understand and easier to debug. Messaging may easily turn into memory leak and in this case I don't see any benefit over my approach.
EDIT:
Will you use custom enum in ShowMessageBox parameters, or will you use
System.Windows.MessageBoxImage?
First of all, ViewModels belong to presentation layer. It is OK to use enums like System.Windows.MessageBoxImage in ViewModel.
In MVVM, ViewModels are separated from Views because of following reasons:
ViewModels expose data and logic from Model in such way that is easily consumable from Views (e.g DataBinding)
ViewModels are easier testable
ViewModels provides better design time support (Blendability, test data)
ViewModels separates application logic from the actual presentation markup which makes it easier to understand (readbility)
Does using enum like System.Windows.MessageBoxImage breaks any of the points above? The answer is no.
If you wanted to reuse IDialogService and your ViewModels on multiple platforms, for example WPF, UWP and Xamarin, then you need to create your own enum, because it may not exist on all platforms. The golden rule is: don't add another layer of abstraction if you don't need it.
You could have the view implement an interface, say INotificationService and then pass the view to the view model constructor. That won't violate MVVM, and you will still be able to bind the view model to the view using the DataContext property on the view.
I decided to keep ViewModel as clean of UI (View) stuff as possible, so I will create custom enumeration inspired by MessageBox and tailored exactly to my needs.
I am trying to find the best practice for creating view models and services (service just talks to the server and return data back to view model). I have seen 2 different approaches.
Using view model locator
Using behaviors (I am not sure if this is good approach)
For the second approach, you define a behavior on UserControl and on attach event you create an instance of view model and an instance of service and put them all together.
protected override void OnAttached()
{
var service = Activator.CreateInstance(ServiceType)
var viewModel = Activator.CreateInstance(ModelType);
base.AssociatedObject.DataContext = viewModel;
base.OnAttached();
}
and in your usercontrol xaml
<i:Interaction.Behaviors>
<be:ViewModelBehavior ViewModelType="{x:Type vm:ViewModel1}" ServiceType="{x:Type serv:Service1}"/>
</i:Interaction.Behaviors>
Is this a good use of behaviors, or I should just use viewmodel locator pattern.
Your behavior has one significant disadvantage - in each usercontrol you have to specify the behavior, ViewModelType (and ServiceType as well).
You can do following:
<UserControl x:Class="MyApp.HomePage" ....
local:ViewModelLocator.AutoWireViewModel="True">
...
</UserControl>
When you set the attached property to true, ViewModelLocator will create the viewmodel instance and assign it to the usercontrol's datacontext. The ViewModelLocatator uses naming convention to determine type of viewmodel. In this case it could be HomePageViewModel, because the view type is HomePage.
This approach is used by PRISM ViewModelLocator from Prism.Mvvm library, but I recommend you to write your own, since it's quite easy.
It is basically similar to your ViewModelBehavior, but the re are two differences:
The behavior is implemented as attached property. It allows you to specify the behavior in Style, so it will be applied to any usercontrol that uses this style. You cannot specify Interaction.Behaviors in styles.
It uses naming convention instead of explicitly set ViewModelType
Regarding the service, that should be passed as a parameter to viewmodel: You can use IoC pattern. This is pseudocode, that describes the pattern:
public class MyViewModel(IMyService service) {...}
//at application startup you setup the IoC container:
IoC.Setup<IMyService>(new MyService());
//later
var viewModel = IoC.GetInstance<MyViewModel>(); //MyService will be passed as to ctor
I'm using Prism and Unity to rewrite a WPF application using the MVVM pattern. Most of the Views are connected to the VM via the DataContext property, like so:
<UserControl.DataContext>
<VM:RibbonViewModel/>
</UserControl.DataContext>
The problem is that this method will not work when there is a parameter in the ViewModel's constructor.
public RibbonViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
}
I get the error:
Type 'RibbonViewModel' is not usable as an object element because it is not public or does not define a public parameterless constructor or a type converter.
How do I connect the VM to the View when a parameter is there?
You might have a look at the sample applications of the WPF Application Framework (WAF). In these examples the IoC Container (in your case its Unity) is responsible to create the ViewModels. This way a ViewModel can have constructor parameters. The IoC Container is also responsible to bring the View with the ViewModel together. Maybe this is an option for your ViewModel design as well.
Consider using a ViewModelLocator. Rather than binding the datacontext to the ViewModel in your case above, you bind to a locator which knows how to resolve the ViewModel from the (unity) container and in the process inject any dependencies into the constructor. There's a blog posting summarizes an implementation by John Papa and Glenn Block (one of the people behind prism).
I believe the EventAggregator is registered with the container by default, so it should be auto-wired with the VM when you resolve the VM from the container.
I should mention the code from the above blog is using MEF. This blog I believe has a codeplex example using unity
I don't use unity or prism. But, why can't you just do this:
userControl.DataContext = ribbonViewModelInstance;
You can have a dependency property on the user control which is set. On setting of value of this dependency property, you can set the datacontext.
I have been reading about MVVM pattern from various sources like MSDN:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
In that article it says: Unlike the Presenter in MVP, a ViewModel does not need a reference to a view.
If the View (XAML) assumes it's DataContext is the ViewModel then where in the code is the following line:
view.DataContext = viewModel;
The ViewModel doesn't know anything about the view so it cannot set the datacontext. If I give the ViewModel the reference do I break the MVVM pattern? My other choice is to have some kind of Builder or extra Presenter whose only job is to wire the whole thing (wait for the loaded event of the View, set the DataContext).
I know different view's can share the same DataContext (e.g. set the DataContext only for the mainwindow and others will see it) but in many cases that is not possible at all nor even feasible.
This is a great question that has many answers. It all depends on how you want to architect your application. For instance, I use dependency injection to create my IViewModel, which in turn creates my IView and my IViewModel runs an IView.SetViewModel(this) on the constructor.
Other people may wish to use a more Blendable method by setting the DataContext in the Xaml:
<UserControl.DataContext>
<ns:CrazyViewModel />
</UserControl.DataContext>
Sometimes the DataContext can be implied so it is set by the framework, like in the instance of a DataTemplate used by an ItemsControl. This is also pretty common in desktop WPF because it supports typed DataTemplates.
So there really isn't a wrong way to set the DataContext, just as long as what you have separates concerns, is maintainable and is also easily testable.
Shawn Wildermuth has a great post about whether the View or ViewModel comes first:
http://wildermuth.com/2009/05/22/Which_came_first_the_View_or_the_Model
I like, and use, his marriage concept where a 3rd party class creates both the view and viewmodel, and then associates the two. It's worked well for me.
I use MVVM a lot in with Prism. In Prism I use Unity for dependecy injection. Therefore I have an interface for every class registered with Unity including the View.
The IView interface has a method like this:
void SetViewModel(object viewModel);
The ViewModel calls this method at the end of its constructor, passing itself as a parameter:
public ViewModel(IView view, ...)
{
...
this._view=view;
this._view.SetViewModel(this);
}
In the View.xaml.cs the IView interface is implemented. This will be the only code I add to the codebehind of the view:
public partial class View:UserControl, IView
{
public View()
{
...
}
public SetViewModel(object viewModel)
{
this.DataContext = viewModel;
}
}
As for my own usage, the ViewModel doesn't know the View, or any interface on the View. And most of time, the View doesn't know its ViewModel, even if it is less important. The VM is just transprted by the DataContext.
This ensures that the VM and V will remain highly independant. Links are established thoughout bindings, commanding, Behaviors, Triggers & so on. Even if VM is often highly related to a given view, I try to make it as generic as possible, so that I can switch the corresponding View, and / or adapt the View behavior without needing to update the VM, except if the architectural link between V and M is impacted !
When implementing the ViewModel in a Model-View-ViewModel architecture WPF application there seem to be two major choices how to make it databindable. I have seen implementations that use DependencyProperty for properties the View is going to bind against and I have seen the ViewModel implementing INotifyPropertyChanged instead.
My question is when should I prefer one over the other? Are there any performance differences? Is it really a good idea to give the ViewModel dependencies to WPF? What else do I need to consider when make the design decision?
Kent wrote an interesting blog about this topic: View Models: POCOs versus DependencyObjects.
Short summary:
DependencyObjects are not marked as
serializable
The DependencyObject class overrides and seals the Equals() and
GetHashCode() methods
A DependencyObject has thread affinity – it can only be accessed
on the thread on which it was
created
I prefer the POCO approach. A base class for PresentationModel (aka ViewModel) which implements INotifyPropertyChanged interface can be found here: http://compositeextensions.codeplex.com
According to the WPF performance guide, DependencyObjects definitely perform better than POCOs that implement INotifyPropertyChanged:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
The choice is totally based on your business logic and UI abstraction level. If you dont want a good separation then DP will work for you.
DependencyProperties will be applicable mainly at the VisualElements level so it won't be good idea if we create lot of DPs for each of our business requirements. Also there is a greater cost for DP than a INotifyPropertyChanged. When you design a WPF/Silverlight try to design UI and ViewModel totally separate so that at any point of time we can change the Layout and UI controls (Based on theme and Styles)
Refer this post also - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . The link has a lot of reference to Model-View-ViewModel pattern, which is very relevant to this discussion.
From an expressiveness standpoint, I thoroughly enjoy using dependency properties and cringe at the thought of INotifyPropertyChanged. Apart from the string property names and possible memory leaks due to event subscription, INotifyPropertyChanged is a much more explicit mechanism.
Dependency properties imply "when this, do that" using easily-understood static metadata. It is a declarative approach that gets my vote for elegance.
Dependency properties are intended to supports binding (as a target) on UI elements not as a source to data binding, this is where INotifyProperty comes in. From a pure point of view you shouldn't use DP on a ViewModels.
"In order to be the source of a binding, a property does not need to be a dependency property; you can use any CLR property as a binding source. However, in order to be the target of a binding, the property must be a dependency property. For a one-way or two-way binding to be effective, the source property must support change notifications that propagate to the binding system and thus the target. For custom CLR binding sources, this means that the property must support INotifyPropertyChanged. Collections should support INotifyCollectionChanged."
All dependency objects cannot be serialised (This could hamper the use of ViewModels and DTO (POCO)'s.
There are differences between DP within Silverlight compared to WPF.
http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx
INotifyPropertyChanged when used also gives you the ability to add more logic in the code of your getters and setter of your properties.
DependencyProperty example:
public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
public String Name
{
set { SetValue( NameProperty, value ); }
get { return ( String ) GetValue( NameProperty ); }
}
In your getter and setter --- all you can do is simply call SetValue and GetValue respectively, b/c in other parts of the framework the getter/setter is not called, instead it directly calls SetValue, GetValue, so your property logic wouldnt reliably be executed.
With INotifyPropertyChanged, define an event:
public event PropertyChangedEventHandler PropertyChanged;
And then simply have any logic anywhere in your code, then call:
// ...
// Something cool...
// ...
if( this.PropertyChanged != null )
{
PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}
// More cool stuff that will reliably happen...
This could be in a getter/setter, or anywhere else.
Is it really a good idea to give the ViewModel dependencies to WPF?
.NET 4.0 will have System.Xaml.dll, so you won't have to take a dependency on an arbitrary framework to utilize it. See Rob Relyea's post about his PDC session.
My take
XAML is a language for describing objects, and WPF is a framework whose described objects are UI elements.
Their relationship is similar to C#, a language for describing logic, and .NET, a framework which implements particular kinds of logic.
XAML's purpose is declarative object graphs. The W*F technologies are great candidates for this paradigm, but XAML exists independently of them.
XAML and the entire dependency system were implemented as separate stacks for WF and WPF, probably to leverage the experience of different teams without creating a dependency (no pun intended) between them.
I too had to consider this decision recently.
I found that the INotifyPropertyChanged mechanism suited my needs better because it allowed me to glue my GUI to an existing business logic framework without duplicating state. The framework I was using had its own observer pattern and it was easy to forward one level of notification on to the next. I simply had a class which implemented the observer interface from my business logic framework and the INotifyPropertyChanged interface.
With DP you cannot define the backend that stores the state yourself. I would have had to let .net cache a copy of every item of state I was binding to. This seemed like an unnecessary overhead - my state is large and complicated.
So here I found INotifyPropertyChanged better for exposing properties from business logic to GUI.
That being said where I needed a custom GUI widget to expose a property and for changes to that property to affect other GUI widgets DP proved the simple solution.
So there I found DP useful for GUI to GUI notification.
Dependency properties are the glue of custom control creation. If you are interested in using Intelli-sense to show your properties in the properties window at XAML design time you must use Dependency properties. INPC will never show a property in the property window at design time.
It seems that Dependency Properties should be used in controls that you create such as Buttons. To use properties in XAML and use all the WPF features, those properties must Dependency Properties.
However, your ViewModel is better off using INotifyPropertyChanged. Using INotifyPropertyChanged will give you the ability to have getter/setter logic if you need to.
I recommend checking out Josh Smith's version of a base class for a ViewModel that already implements INotifyPropertyChanged:
http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
I think this is an excellent example of how to do a ViewModel.
I think DependencyProperty and INotifyPropertyChanged are used for two different things in Binding : the first for enabling a property to be a target of a binding and receive the input from another property (use {Binding ...} to set the property), the last when you want the value of a property to be used as the source of a binding (name in the Binding Path Expression).
So the choice is merely technical.
I prefer a more direct approach, which I blogged about in Presentation Model Without INotifyPropertyChanged. Using an alternative to data binding, you can bind directly to CLR properties without any bookkeeping code. You just write plain-old .NET code in your View Model, and it gets updated when your Data Model changes.
There is only one thing why to prefer a DependencyObject - Binding will work better. Just try an example with a ListBox and TextBox, populate list with data from INotifyPropertyChanged property vs. DependencyProperty and edit current item from TextBox...
If you want to expose properties to other controls you must use Dependency properties... But good luck because they take a while to figure out...