Correct MVVM design patterns - ViewModel and DataContext - wpf

I started playing around with Windows Phone development. I am using MVVM ligth and I am trying to follow good practices. But lately I ran into an issue:
Is it okay to use ViewModel inside a ViewModel as a property?
My scenario is that I am having a MainViewModel which is a Panorama object. This Panorama objects consists of few PanaoramaItems (Notes, Calender and About Controls/Pages).
My question is, if I have for the MainPage.xaml a MainViewModel, is it okay if I put the other ViewModels as properties (NotesViewModel, CalenderViewModel, AboutViewModel) to the MainViewModel, in that case those will inherit from the MainPage the DataContext and I would just bind to a property of the MainViewModel. Or should I rather use the locator pattern to allow the other pages/control to get their own ViewModels and do not inherit the DataContext?
Is it okay, if a control has a ViewModel or should it be rather for pages?

If the Parent and Child ViewModels are related: sure, that is fine, it does not violate the pattern.
This setup allows you to re-use ViewModels and Views across pages and controls.

Related

WPF Prism Unity Container. Setting keyboard focus on usercontrol or usercontrol grid parent

I'm working on a project that utilizes WPF, using the Prism library and Unity Container.
I have a mainwindow, which contains a mainviewmodel control which in turn is populated by a collection of user controls.
My goal is to set keyboard focus to the mainviewmodel where I have an EventTrigger InvokeCommandAction which reacts to keyeventsargs...
Currently the only way the command is fired if I use a textbox within the control (or child controls). My goal is to have the mainviewmodel control or grid get and preserve keyboard focus.
Any tips would be appreciated!
//Nathan
Either not understanding your question correctly or you should review the basic concepts of MVVM in a WPF implementation.
The View is the WPF controls.
WPF Window/UserControl files contain WPF markup which is the View.
Controls in a view leverage DataBindings to the DataContext property of either the control itself or the parent containing control (which it will inherit).
DataContext property is set to an instance of an object that is the ViewModel. It contains properties to hold values and commands to execute actions.
So conceptually there is no "mainviewmodel control", there is a MainView which contains controls and may in this case have its DataContext property set to an instance o MainViewModel. (hence my confusion)
Finally, while it is possible and some might even recommend writing UI rules/logic in a view model I haven't found much benefit in it.
You are much better off putting UI logic in the XAML or in the MinView code behind. You can still access the MainViewModel in the code behind by casting the MainView.DataContext property as a MainViewModel.
So for example:
MainView.KeyDown event can be wired up to call MainViewModel.CommandX.Execute();

MVVM and Custom Controls?

I'm working on PRISM application with modules, MVVM and so on. I understand PRISM pretty good now and I understand value of MVVM. All those things good to deliver business value which comes from testability, "uniformity" and so on.
But now I'm stuck with certain interaction issues. I already spent hours and hours trying to see how I set focus in Silverlight via MVVM. All this additional behaviors, attached properties, triggers. It just seems like bunch of junk code with MVVM being root cause.
For example, I need to create Lookup control which is basically textbox with button and popup window. This control itself needs lot of focus control, it needs to overlay view over parent (popups) and so on. It seems to be pretty easy to create it with code-behind, stick it into separate library and move on. My business forms will use this control inside my nice MVVM PRISM.
So, question is.. Is it justified to use code-behind in isolated islands like controls and keep MVVM and TDD for actual code that brings business value?
Is there line where you say "MVVM is not going to be used here" ?
I see absolutely nothing wrong with using Code Behind providing that the code is related to view-specific properties, such as setting Focus. Your ViewModel should never need to know about or care who or what has focus, since that is a View-Specific concept.
Usually I build UserControls in two ways: they are either built for a specific Model or ViewModel, or they are meant to be generic and have their values provided by whoever calls them.
In the case of the former, such as if I wanted a SearchResultsPopup, I would build the UserControl expecting to have something like a SearchResultsViewModel as the DataContext.
For example, my UserControl would expect to find the following properties on it's DataContext, and would use them in bindings to build the View.
ObservableCollection<SearchResult> Results
SearchResult SelectedResult
bool IsOpen
ICommand OkCommand
ICommand CancelCommand
I could then use the UserControl like this:
<local:SearchResultsPopup DataContext="{Binding MySearchResultsVM}" />
In the later situation, where I am creating something generic which can be used by any Model or ViewModel, I would use custom Dependency Properties to provide my UserControl with the values it needs to bind to.
So in this example, I would have DependencyProperties for
bool IsOpen
ICommand OkCommand
ICommand CancelCommand
And my XAML would look something like this:
<local:GenericPopup local:GenericPopup.IsOpen="{Binding IsPopupOpen}"
local:GenericPopup.SaveCommand="{Binding SavePopupCommand}"
local:GenericPopup.CancelCommand="{Binding HidePopupCommand}">
<local:MySearchResultsView ... />
</local:GenericPopup>
In summary, your UserControl is either a reflection of your ViewModel (meaning it becomes a View), or it is provided values by the View. The ViewModel doesn't care either way.

WPF MVVM: How do ViewModels communicate with each other?

I have a View which has 2 sub views on it and a ViewModel is assigned to each view:
ViewA - ViewModelA
{
ViewB - ViewModelB
ViewC - ViewModelC
}
ViewB has a text box and ViewC has a combobox, both of which i need access from ViewModelA. Not the GUI control itself, but the bound value i.e. .Text of the textbox and .SelectedItem of the ComboBox. Currently i just have ViewModelB and ViewModelC as properties on ViewModelA but it feels wrong.
What's the standard way for view models to communicate with each other without breaking the MVVM pattern?
One way to have disconnected ViewModels communicate to each other is to use a publish / subscribe mechanism such as PRISMs EventAggregator. However, in a parent / child ViewModel relationship, I think it's fine for the parent to have direct knowledge and control over the child ViewModel.
Personally, I don't think composing a ViewModel out of other ViewModels is a bad practice. I do it all the time. I generally favor composition over inheritance in my ViewModels.
The ViewModels usually 'inherit' relationships from the Model. And it's not wrong to add a relation when it makes sense.
It's perfectly OK for a ViewModel to have a property referring to another ViewModel.

MVVM multiple views

Im trying to learn MVVM so far its going well , I have stumble on a situation which I don't know how to implement ..
What I want :
- A view with left navigation and right details pane .. right details will have a contentcontainer which would hold my User Controls for the views to be selected by left pane
What I have :
- A MainViewModel
- ViewModels for Each of the Entities I have on my database
My Problem :
- Since I will have an ObservableCollection of my VIEWMODELS in my MAINVIEWMODEL ( as per the example i'm patterning my application ) do I create a public property for each of my MODEL Entities which will be used for the databinding I have defined in my UserControls ??
You can create a Base Type for all of your ViewModels to be displayed on the right side.(lets call that as BaseContentViewModel)
Then your left side ListBox will be bind to ObservableCollection<BaseContentViewModel> and the SelectedValue of the ListBox will bind to a new MainViewModel.SelectedContent proeprty of Type BaseContentViewModel.
And on the right side you need to have a ContentControl to which SelectedContent bind to ContentControl.Content
Now it is just a matter of defining different UserControls as DataTemplates in the Resource XAMLs (Usually refers as ViewToViewModelMapping in MVVM)
Have a look at John Papa's PDC talk 'Advanced Topics for Building Large-Scale Applications with Microsoft Silverlight'. In it he illustrates an approach for managing an application that has multiple MVVM triads.

MVVM: CollectionView in ViewModel or CollectionViewSource in xaml?

I'm developing a WPF application using the MVVM pattern and I need to display a list of items in a ListView (with filtering), with the fields of the selected item displayed in a Master/Detail view. I'm torn between the following two ways of doing this:
Exposing a CollectionView in my ViewModel, and binding to this.
Exposing a plain IList in my ViewModel, and using CollectionViewSource to create the CollectionView in XAML.
Is there an accepted way of doing this? Any thoughts on the best way?
I do the former (expose CollectionView from the VM) but what really matters is where your filtering logic is. That should definitely be in the VM so that it can be tested, even if the view has to wire up the CollectionViewSource to the VM. That said, I don't think there's anything particularly nasty or anti-MVVM about exposing a CollectionView from your VM.
I know I'm a bit late answering your question but I just saw it today.
I have created master/detail viewmodels that use the CollectionViewSource and blogged about it.
I wrote about a viewmodel for master/detail tables here that uses :
http://reyntjes.blogspot.com/2009/04/master-detail-viewmodel_24.html
You can also find a viewmodel for the observablecollection class on my blog pages.
Maybe you find it of use to you.

Resources