Is it possible to wire up the View and ViewModel using both a Declarative DataContext and a Data Template?
Goal: I want to wire Views with a one ViewModel for design-time and another at run-time. Currently, using a Declarative DataContext for a design-time VM and a Data-Template-specified VM for runtime doesn't behave as expected.
Background - There are a variety of ways to wire up a View and ViewModel including the following:
A.) Declaratively specify the ViewModel DataContext within the View’s XAML. This technique is useful at Design-Time using the parameter-less constructor to pass in dummy data.
<UserControl.DataContext>
<my: BrowseAssetsViewModel />
</UserControl.DataContext>
B.) Programmatically specify the ViewModel, View and DataContext.
// …Setup code
BrowseAssetsViewModel viewModel = new BrowseAssetsViewModel(assetRegistry, domains);
BrowseAssetsView view = new BrowseAssetsView();
view.DataContext = viewModel;
When Approach B is used in combination with Approach A, at run-time WPF overrides the default DataContext specified in Approach A using the version of the ViewModel with the parameterized constructor specified in Approach B.
C.) Define a Data Template for the View-ViewModel association By associating a View and ViewModel in App.XAML Application.Resources, WPF can wire up the correct View based on a ViewModel’s type.
<DataTemplate DataType="{x:Type vm: BrowseAssetsViewModel }">
<vw: BrowseAssetsView />
</DataTemplate>
If a ViewModel property were bound to a ContentPresenter control, WPF would wire-up the corresponding View (based on the ViewModel’s type) and place it within the ContentPresenter. This is useful in the “ViewModel-first” scenario where the ViewModel is presented and WPF resolves and wires the correct View by inspecting the presented ViewModel’s type.
Problem - When using this Approach C in combination with Approach A, WPF resolves the correct View but it seems to then re-query the View, calling the declaratively specified ViewModel via the parameter-less constructor (Approach A), thus overriding the existing ViewModel property!
Question - Is there a way to use these techniques (C and A) together without A inadvertently overwriting the C ViewModel property?
You can specify that the DataContext is in case A set only only at design time, like so:
<UserControl ...
d:DataContext="{d:DesignInstance my:BrowseAssetsViewModel}"
>
For details, see Using a DesignInstance... on MSDN.
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