I have recently started investigating the MVVM pattern with WPF for an upcoming project. I started with Josh Smith's MSDN article. I have a question (well many, but let's start with one):
I have an IndividualViewModel which exposes the properties of the model. I need two views "Add Individual" and "Edit Individual" which are very similar as you can imagine. What I have done currently is to have 2 subclasses AddIndividualViewModel and EditIndividualViewModel which expose the Add and Edit commands respectively. I also have 2 similary named views that bind to these.
Now this method works and these classes are fairly small anyway, but I'm wondering if it is possible for me to have just the one view model, which exposes both commands. I would still have 2 views which would bind to this same view model, exposing the appropriate command as a button. I'm not quite sure how to do this. In the main window resources I have something like:
<DataTemplate DataType="{x:Type ViewModels:AddIndividualViewModel}">
<Views:AddIndividualView />
</DataTemplate>
With this method of binding you can only have a one-to-one binding, i.e. the same view is always shown for a given view model. Is there a way to automatically switch the view depending on a property on the view model (e.g. IndividualViewModel.Mode). Is there a different approach I should be considering?
Note that the main window has a collection of view models and shows each in tab.
Thank you!
It's possible that having two separate views is what you want, but it's just something to consider. Show activity on this post. Define the viewmodel as singleton (code smell) or. Using the RegionContext (for full description see the prism doc)
No that is fine; each object should be a ViewModel in its own right.
ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property. It should not contain any method. In the above example, we have the required View model with two properties.
So you need 2 different views based on a property value. One thing to consider is to refactor your presentation code, so instead of the values of a property you could have real subclasses. Then you can use 2 different DataTemplate
for each class.
<DataTemplate DataType="{x:Type ViewModels:AddIndividualViewModel}">
<Views:AddIndividualView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:EditIndividualViewModel}">
<Views:EditIndividualView />
</DataTemplate>
If you think that is an overkill, you could use a trigger and wrap your specific views into a ContentPresenter
.
<DataTemplate x:Key="AddIndividualTemplate" DataType="{x:Type ViewModels:IndividualViewModel}">
<Views:AddIndividualView />
</DataTemplate>
<DataTemplate x:Key="EditIndividualTemplate" DataType="{x:Type ViewModels:IndividualViewModel}">
<Views:EditIndividualView />
</DataTemplate>
<DataTemplate DataType="{x:Type ViewModels:IndividualViewModel}">
<ContentPresenter Content="{Binding}">
<ContentPresenter.Style>
<Style TargetType="ContentPresenter">
<Setter Property="ContentTemplate" Value="{StaticResource AddIndividualTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Mode}" Value="{x:Static ViewModels:IndividualMode.Edit}">
<Setter Property="ContentTemplate" Value="{StaticResource EditIndividualTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</ContentPresenter.Style>
</ContentPresenter>
</DataTemplate>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With