Microsoft Developer Network >
Forenhomepage
>
Windows Presentation Foundation (WPF)
>
Requesting a specific ViewModel from the View?
Requesting a specific ViewModel from the View?
- I am working on the architecture for a custom user control. Basically, it has a very specific and custom layout, and I need to place specific elements in specific locations. The elements themselves are ViewModels pulling data from a model.So for example, if I have a ObservableCollection of SubViewModel elements, each with an ID field, that are within a MainViewModel. From the MainView, because of this custom layout, the SubViewModel with ID=1 has to go in position 1 (wherever that may be), the SubViewModel ID=2 goes somewhere else etc.I cant just assign a DataContext here(?) because of the custom layout, but I also dont know how to do something like:<viewmodel:SubViewModel Grid.Column=2 ID="1" />And have the right SubViewModel retrieved and displayed.What is the right way to do this? Is there a way for the view, in XAML to request a specific element from the viewmodel?Or am I just totally confused, and on the wrong track? (certainly possible!)
Antworten
- Hello,
Have an observable collection of viewmodels (SubViewModels here) is a good approach. If you want to list and show the detail of each SubViewModel you need an items control (a control that can show multiple items) and create a data template for the subitem. For example:
<ItemsControl ItemsSource="{Binding SubViewModelList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- Your data template to show SubViewModels -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Good Luck.- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
- Personally, I would use the following approach:
Each section of your main view would be its own control and have its own ViewModel. The controls would not know anything about each other and the view would be free to arrange them in any way it wanted to. The communication between the ViewModels would be handled by a Mediator (here's an example/brief overview: http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/ ). Your main view, in this scenario, would act more like a shell that simply encapsulates the different pieces of your app.- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
In this case, using your 4 section examples, the SubViewModel for position 1 will -always- be ID=1. Some other data elements may change in the model and get displayed in a 'SubElement' view, but thats all that would change.
If your properties on the ViewModel are just setup like:It sounds like I was headed in the right direction with the controlling viewmodel, but Im not sure how to use DataTemplates to pull specific SubViewModels out of the main ViewModel for each position?
public object Position1Object { get; set; } // +Implement INotifyPropertyChanged, alternatively, use a base class for your VM here instead of object
Then the MainViewModel can set ANY object (ViewModel) into that position. The view would just have a content presenter for each position, and the ViewModel can place any control into positions 1-4 at will. This gives you complete control over how things are rendered in the view side, and the actual content used on the ViewModel side, with no coupling between the two.
The DataTemplates can match ViewModel->View for you.
Reed Copsey, Jr. - http://reedcopsey.com- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
Alle Antworten
- I normally handle this by having a "controlling" viewmodel. For example, say your view will have 4 sections (position 1 - 4). If the content within those is changing at runtime, the ViewModel can be used to coordinate this. It just needs 4 properties, one for the object (ViewModel) that goes into each position.
The view can then just setup 4 separate content presenters, each bound to the relevant property in the ViewModel. If there is a data template setup to map each potential ViewModel -> View, it's just a matter of having the main VM set ViewModels to the 4 properties when it wants to change things around, and the Views automatically keep in sync.
Reed Copsey, Jr. - http://reedcopsey.com - Hello,
Have an observable collection of viewmodels (SubViewModels here) is a good approach. If you want to list and show the detail of each SubViewModel you need an items control (a control that can show multiple items) and create a data template for the subitem. For example:
<ItemsControl ItemsSource="{Binding SubViewModelList}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- Your data template to show SubViewModels -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Good Luck.- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
I normally handle this by having a "controlling" viewmodel. For example, say your view will have 4 sections (position 1 - 4). If the content within those is changing at runtime, the ViewModel can be used to coordinate this. It just needs 4 properties, one for the object (ViewModel) that goes into each position.
In this case, using your 4 section examples, the SubViewModel for position 1 will -always- be ID=1. Some other data elements may change in the model and get displayed in a 'SubElement' view, but thats all that would change.
The view can then just setup 4 separate content presenters, each bound to the relevant property in the ViewModel. If there is a data template setup to map each potential ViewModel -> View, it's just a matter of having the main VM set ViewModels to the 4 properties when it wants to change things around, and the Views automatically keep in sync.
Reed Copsey, Jr. - http://reedcopsey.comIt sounds like I was headed in the right direction with the controlling viewmodel, but Im not sure how to use DataTemplates to pull specific SubViewModels out of the main ViewModel for each position?- Thanks Homero, seems like that is headed in the right direction too. Im not sure how I would do the DataTemplate part though, since I need to put SubViewModel ID=1 in one spot, ID=2 in another fixed (and custom) position in the layout.
- Personally, I would use the following approach:
Each section of your main view would be its own control and have its own ViewModel. The controls would not know anything about each other and the view would be free to arrange them in any way it wanted to. The communication between the ViewModels would be handled by a Mediator (here's an example/brief overview: http://joshsmithonwpf.wordpress.com/2009/04/06/a-mediator-prototype-for-wpf-apps/ ). Your main view, in this scenario, would act more like a shell that simply encapsulates the different pieces of your app.- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
In this case, using your 4 section examples, the SubViewModel for position 1 will -always- be ID=1. Some other data elements may change in the model and get displayed in a 'SubElement' view, but thats all that would change.
If your properties on the ViewModel are just setup like:It sounds like I was headed in the right direction with the controlling viewmodel, but Im not sure how to use DataTemplates to pull specific SubViewModels out of the main ViewModel for each position?
public object Position1Object { get; set; } // +Implement INotifyPropertyChanged, alternatively, use a base class for your VM here instead of object
Then the MainViewModel can set ANY object (ViewModel) into that position. The view would just have a content presenter for each position, and the ViewModel can place any control into positions 1-4 at will. This gives you complete control over how things are rendered in the view side, and the actual content used on the ViewModel side, with no coupling between the two.
The DataTemplates can match ViewModel->View for you.
Reed Copsey, Jr. - http://reedcopsey.com- Als Antwort markiertsaxisa Mittwoch, 4. November 2009 21:22
- I like that, makes sense to me. Thanks all for the excellent replies!

