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.
Related
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.
In a Windows 8 style app I have a View (or page) which is made up of several other Sub-Views.
Each of these has an associated ViewModel and they are defined and bounded via the MVVM Light ViewModelLocator
I then have a View2 which is made up of other Sub-Views which, again, are defined and bounded via the MVVM Light ViewModelLocator
What I want to do is to place instances of the View and View2 controls into a List on a MasterViewModel and then bind this list to a GridView on a MasterView file.
Each of the instances of View and View2 should render as they do if you were to create a single instance without placing it into a list.
What I have tried to do is create a List of Pages (as all views are instances of this type) and bind the GridView to this, but when I run the app the GridView appears empty.
I have seen an examples that use a DataTemplateSelector (http://www.wiredprairie.us/blog/index.php/archives/1705) and apply a DataTemplate to each of the items in the MasterView list.
I understand what this does, but what I don’t understand is how to create a DataTemplate for a View that is made up of other Views.
I’m sure I am overlooking something and / or just making this harder than it needs to be!
Thank you for any help :)
Normally in this case, you would be binding a list to a set of ViewModels, not views, and the data template selector (or ValueConverter depending on your flavour) would select and instantiate a view suited to the view model.
So if ViewA uses ViewModelA : ISubViewViewModel, and ViewB uses ViewModelB : ISubViewModel then your main ViewModel would contain a List<ISubViewModel> which has a set of ViewModelA & ViewModelB within it. The main view's ListBox is bound to the List<ISubViewModel> and the data template selector / ValueConverter resolves ViewA for ViewModelA's and ViewB for ViewModelB's.
Hope that makes sense, it's about as hard to describe the solution as it probably was to describe the problem. :)
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.
I have a MainView with a Tabbed UI.
How do I add a new TabItem (= View) to the TabControl?
Basicaly I see 2 ways:
1.)
* from code in the MainView I can add a new tab.
* the new tab contains a view with a referece to it's viewmodel.
2.)
* from code in the MainViewModel I can add a new viewmodel to a List of childViewModels
* the tabcontrol of the mainView is bound to that list
I prefere case #1 somehow, cause I think the view should know and instanciate it's VM (maybe by using the MVVM light ViewModelLocator) and not the other way round.
But how can I refere from the newly created VM to the MainVM? For example: the MainVM has a property 'IsAdmin'; how can I access (bind) that property from the SubViewModel?
alternative #2: how does the TabControl know, which view should be "rendered" for different ViewModels? How can I "map" from the SubViewModels to the corresponding "SubViews"?
Thanks for sharing your ideas!
I would check out this SO post as the answer can be applied to helping you with your problem.
In the spirit of MVVM, you will want to follow alternative #2. Let your ViewModel logic help you determine which "tabs" you need to display and use DataTemplates to represent those objects. Then you will get them bound to the DataContext of the View and your binding in the DataTemplate (View) will work correctly.
Thomas,
MVVM really is MVVMC. I would advise having a controller for the MainView which contains a method for creating a new tab. If the TabControl is complicated, you might put the functionality in the TabControl itself.
Separation of concerns (MODEL versus VIEWMODEL versus VIEW versus CONTROLLER) is compromised when actuation functionality is located in the models. (M or VM).
Regards,
Guido
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.