MVVM model instantiation - wpf

Following WPF MvvmFoundation, linking the View with the ViewModel has many choices like described on http://www.paulstovell.com/mvvm-instantiation-approaches.
However their example has nothing about how to link the ViewModel with the Model.
Traditionally I created the model first and then one or more views that render it. It seems that MVVM pushes people to create the View, which creates the ViewModel, which create the Model. I hope it's not the case as wiring a complex business model with various ModelView can else be tough.
How do you instantiate your business model classes in MVVM and link them with your ViewModels?

I normally pass Model objects as constructor params to VM. I use App class as the controller which will initialize MainWindow, MainWindowViewModel with the main model. There after the MainWindowViewModel takes care of initializing other VMs with appropriate model objects.
private void Application_Startup(object sender, StartupEventArgs e)
{
mainWindow = new MainWindow();
mainWindow.DataContext = new MainWindowViewModel(new Model());
mainWindow.Show();
}

You create your BusinessModel classes inside your ViewModel.
So in your CustomerViewModel you would say this.CurrentCustomer = new CustomerModel(), and your CustomerView would bind to the CurrentCustomer property on the ViewModel
If you are interested, I wrote up a simple sample using MVVM as an example of how the View, Model, and ViewModel interact.

I use dependency injection/MEF to do this. Just export all of my model classes all the way down the chain, and have them imported for me automatically into the ViewModel constructor.

I take a variety of different approaches depending on the situation. I've found that when it comes to getting this data linked, one size does not fit all.
For simple cases, I will have the ViewModel and the Model be the same thing. Obviously not that good for all cases, but sometimes there is just no need to go the extra mile to split the M from the VM. (Great for cases where you have, say, listbox items that have scant information)
Sometimes, especially when the model is a chunk of code you don't have access to (written by another developer) it is easy to subclass the model, and add all of your VM things (observable properties, etc.) on to it.
Lastly, I will use the approach that is mentioned by Souvik. Construct the VM with the model information that you want to use as a parameter, or allow it to be passed in otherwise. This is probably the most common approach for my larger and more complex Model / ViewModel relationships.

I am auto-passing IRepository instance to VM constructor using IoC container and everything VM needs to do with models is done via this repository. Repository is class which: Create, read, update and delete data. When I need to show some view (window), I use IViewService.ShowDialog(viewModel As ViewModelBase). In implementation of IViewService, there are views registered with VMs, so VMs only need to know other VMs and not their views (like "Show me view for this view model").

Related

MVVM: Loosely coupling of ViewModels

I have classes, A, B, C, D
A has a reference to E and B and to a list of C and D.
In AViewModel these are exposed in a tree.
The View for A looks like as in the picture.
When a node selected a correspondent view should be displayed.
There is ViewModels for E,B,C and D
My question is the following:
For example E is the selected node. I store it in AViewModel as "object SelectedItem".
What is the best way to create an EViewModel in a loosely coupled way, so that I do not want to reference EViewModel in AViewModel.
Update:
I was thinking about one solution, but I never seen that in other places:
For example I could expose only my POCOs (B, C, D, E) from AViewModel. And in XAML I could bind the ContentControl directly to these objects. With a converter I could have a BViewModel when I bind to B and so on.
A common and widely accepted way to communicate between view models and other components in a loosely coupled way in an MVVM application would be to use an event aggregator or a messenger. Please refer to the following links for more information.
Using the event aggregator pattern to communicate between view models: https://blog.magnusmontin.net/2014/02/28/using-the-event-aggregator-pattern-to-communicate-between-view-models/
MVVM - Messenger and View Services in MVVM: https://msdn.microsoft.com/en-us/magazine/jj694937.aspx.
Another option would be to use a shared service that you inject the view models with: https://social.msdn.microsoft.com/Forums/en-US/22907a0f-d805-4195-8272-7c284b72d2ee/example-of-using-shared-services-prism?forum=wpf
Using an event aggregator, messenger or shared service means that you can remove all references between the view model classes.
Instead of the view model classes having strong references to each other back and forth, each view model only knows about a single event aggregator/messenger/shared service and communicates only with this one. View model A may send any number of messages that any other view models may subscribe to listen to and handle internally.
My question is about best practices on topic of creating an instance of a ViewModel without having a tight coupling, not about the communication between loosely coupled ViewModels
Creating an instance of another view model without creating a string coupling is impossible. If one view model creates an instance of another view model they are by definition strongly coupled. To prevent this you could inject a view model with an interface type that the other view model implements, e.g.:
public ViewModelB(IViewModelA viewModelA)
{
//...
}
Then ViewModelB is dependant on an interface type instead of a concrete implementation of the ViewModelA. It's a bit better than doing something like this because then ViewModelA and ViewModelB will always be - as mentioned above - strongly coupled to each other:
public ViewModelB()
{
_viewModelA = new ViewModellA();
}
But if you really care about loose coupling between your view model classes, you should get rid of the direct references and start to use an event aggregator or a messenger to communcate between them.
If your A View displays the "list", plus the selected view, it's perfectly acceptable to have EViewModel reference in AViewModel. ViewModels may be the "reflection" of the views. So if the A view will contain an EView, AViewModel may contain an EViewModel. You just nest your view models so it creates the same tree as in the view layer.
On top of that, what I would do is not reference E or B,... in AViewModel, but reference only EViewModel, BViewModel,... So AView list does not display model classes but ViewModel classes. Your SelectedItem gets typed as a ViewModel and you can directly bind your "Display" view part to the SelectedItem. Then you can use the right DataTemplate on the view layer to display the according view. Hope it helps

Notification from ViewModel to View

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.

Composite WPF: Data Template vs. View Model Injection

Here is the simple question: what do you use to link your views to your view models?
Basically there is 2 common ways of achieving that, data templates and view model injection (samples below).
What I would like to know is why do you prefer a method over the other and in which case you use them. Precise the MVVM framework you use.
The data template way or "View Model first" approach (Resources.xaml):
<DataTemplate DataType="{x:Type my:PersonViewModel}">
<my:PersonView/>
</DataTemplate>
The view model injection way or "View first" approach (PersonView.xaml.cs):
[Import]
public PersonViewModel ViewModel
{
set
{
this.DataContext = value;
}
}
I prefer using DataTemplates
It allows me to set multiple Views for the same ViewModel based on a property
My ViewModels are my application, and the View is nothing more than a pretty layer that makes my ViewModel's User-Friendly. If I use ViewModel injection, than the Views become my application and the development team suddenly has to worry about the UI side of things
My ViewModels are managed by other ViewModels. For example, one ViewModel might contain a collection of other ViewModels that get displayed in a TabControl. Adding or Closing tabs is done within the parent ViewModel. This sort of thing is not easily accomplished with the View controlling the application state.
I can initialize different ViewModels using parameterized constructors based on my needs instead of having to use generic Import ones
That's just a few reasons... I'm sure there's others but they don't come to mind right now
We use a view model first approach because we find it easier to manage, particular on larger scale enterprise apps. We use Caliburn.Micro to take care of view location and binding.
I use both. DataTemplates for small projects, but for larger or team projects we use view model injection.

Who sets DataContext in Silverlight MVVM

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 !

How to further decouple this WPF example toward MVC, MVP, or MVVM?

I've decoupled events in this WPF application in the following way.
What is the best way to continue decoupling?
Shell.xaml:
<Button x:Name="btnProcess"
Content="Process"
Margin="10"/>
Bootstrapper.cs:
public void Run()
{
Shell shell = new Shell(new Customer());
shell.Show();
}
Shell.xaml.cs:
public Shell(IPerson person)
{
InitializeComponent();
btnProcess.Click +=new RoutedEventHandler(person.Process);
}
Customer.cs:
public class Customer : IPerson
{
public void Process(object sender, RoutedEventArgs e)
{
Button theButton = (Button)sender;
theButton.Content = "Customer processed.";
}
}
The above code successfully decouples the view Shell from the model Customer:IPerson so that I can swap in e.g. a model Employee:IPerson etc. which handles "Processed" in its own way. That was the first goal.
But now:
how do I decouple the Processed method from talking specifically to a Button, so that it could also talk to a MenuItem or a ListView which fires the event in the view and so that it doesn't even have to be an element at all that calls it, e.g. a unit test class?
how do I alter other elements of the view other than the sender (Button), e.g. how would I alter the status bar in Shell? I see two ways:
I could either build a container which holds all views and inject the container in the Customer upon creation, then the customer can look in the container and manipulate the calling view anyway it wants (although I would have to somehow match the view that sent the event and the view in the container as the same one)
I could somehow send the whole view (Window object) to the Model with the eventargs when firing the event, although the Model would need some way of knowing (via interface) what kinds of regions were available to manipulate at runtime
How would you continue this application in the direction of a more decoupled design?
What pattern is this actually, e.g. MVC, MVP, MVVM? I only see a view (Shell) and a Model (Customer).
How would a Presenter fit in?
How would a ViewModel fit in?
How would a Controller fit in?
I suggest you to implement your event handling using commands instead of classic events.
Its very easy in WPF because the command pattern is already implemented, and you can tell all of your UI inputs (button, menu item...) that their command is [name of your command] and handle all of them in one place.
Cameron MacFarland did a good job here, but I can add a little.
When following M-V-VM, the tools in your box for decoupling are data binding, commands, attached behaviors and interfaces. Data binding should be self evident. You've already gotten a good description of commands, but I'd suggest you avoid RoutedCommand and stick with an ICommand implementation. Attached behaviors are attached DependencyProperty's that subscribe to events on the element they are attached to, and in this scenario would be used to relay event handling to the ViewModel. Interfaces give you the greatest flexibility, but you have to work out how to pass the interface to the ViewModel. The best way to learn all of this right now is to Google and to look at existing M-V-VM frameworks. Here's a list of frameworks:
Prism/Composite WPF (http://www.codeplex.com/CompositeWPF). This one comes from the Microsoft Patterns & Practices group. Lots of good stuff here, but one of the examples of the three things above that you can learn from here is how to use ICommand. Prism includes a DelegateCommand that implements ICommand and simplifies using commands from a ViewModel in M-V-VM.
Caliburn (http://www.codeplex.com/caliburn). Recently released, one of the key things you can learn from this one is how to use attached behaviors, which this library uses for it's "Actions".
Onyx (http://www.codeplex.com/wpfonyx). Disclaimer: I'm the author of this one. This one hasn't been released yet, though the current alpha source is available. This one provides a novel solution to the problem of how to provide interfaces to your ViewModel.
As Chen suggests, i'd look into the Command pattern: Routed commands
A working example from which i learned a lot can be found on Jaime Rodriquez his blog: Southridge
how do I decouple the Processed method from talking specifically to a Button
Commands. Put a command in the IPerson interface and call that command from the Shell's xaml.
how do I alter other elements of the view
Properties and Binding. If you have a property showing the state (processed/not processed) then you can use binding to display that property directly in the xaml.
How would you continue
I'd head more down the MVVM path by creating a ViewModel between the Shell and the IPerson. The ViewModel is designed to have 1) The properties needed for bindings, and 2) any Commands that need executing. The ViewModel is designed to provide the UI with what it needs from the Model.
What pattern is this
Currently? Nothing. I see only two objects, the View and the Model. You don't have a Presenter, Controller or ViewModel.
For WPF I prefer ViewModel. See this question for more info on MVVM.

Resources