This week, a user of Catel approached me with the following question:
“I have a shape view and a ShapeBaseViewModel. Then, I have models such as Rectangle, Circle, etc, and each model has its own view model (RectangleViewModel, CircleViewModel, etc). How can I solve this issue using Catel?”
Excellent question, and I had to admit that this is currently not possible without setting the view model yourself. However, that would kill the super feature of Catel to solve the nested user control. So, I came up with the following solution.
How to dynamically determine the view model using a UserControl
Determining the view model dynamically when using the UserControl is extremely easy. You can override the GetViewModelType(object) method like this:
1: protected override Type GetViewModelType(object dataContext)
2: {
3: if (dataContext is Rectangle)
4: {
5: return typeof (RectangleViewModel);
6: }
7:
8: if (dataContext is Circle)
9: {
10: return typeof (CircleViewModel);
11: }
12:
13: return null;
14: }
When the method returns
null, it will fall back on the earlier determined view model type.
How to dynamically determine the view model using a behavior
Determining the view model dynamically when using behaviors must be done via the DetermineDynamicViewModel event like this:
1: mvvmBehavior.DetermineDynamicViewModel += (sender, e) =>
2: {
3: if (e.DataContext is Rectangle)
4: {
5: e.ViewModelType = typeof (RectangleViewModel);
6: }
7:
8: if (e.DataContext is Circle)
9: {
10: e.ViewModelType = typeof(CircleViewModel);
11: }
12: };
There is no need to set the e.ViewModelType to null because that is the default value.
How can I try this feature?
Install the latest version of Catel using this command in the NuGet package manager shell:
install-package Catel.Extensions.Controls -includeprerelease