I'm trying to build a set of typical CRUD maintenance forms in WPF - that are going to be pretty much the same except that they work on different database records.
Rather than creating a new window class for each, I'm trying to use a single window class that instantiated with a different ViewModel class for each database table, and for which I have a different UserControl defined for each ViewModel.
So, if I instantiate the window with its DataContext set to an instance of Record1ViewModel, I want to display it in the window using a Record1UserControl, if it's set to an instance of Record2ViewModel, I want to display it using a Record2UserControl.
I've verified that both user controls work fine, by defining them each directly in the window's XAML. But I've not figured out how to select one or the other, based on the type of the ViewModel.
This is not working:
<myWindow.Resources>
<DataTemplate x:Key="{x:Type ViewModels:Record1ViewModel}">
<MaintenanceControls:Record1 />
</DataTemplate>
<DataTemplate x:Key="{x:Type ViewModels:Record2ViewModel}">
<MaintenanceControls:Record1 />
</DataTemplate>
</myWindow.Resources>
<ContentPresenter Content="{Binding}" />
What I get, in the ContentPresenter, is the name of the type. The DataTemplates are not used.
Any ideas?
This is a summary of the above link. DataContext should not be set to Self at UserControl Element level. This is because it breaks the Inheritance of the DataContext. If you do set it to self and you place this control on a Window or another control, it will not inherit the Windows DataContext.
By setting the UserControl DataContext to itself, this overwrites the DataContext and breaks Inheritance. Instead, nest it one Element deep in the XAML, in your case, the StackPanel. Put the DataContext binding here and bind it to the UserControl. This preserves the Inheritance.
If the control is depending on some VM or is tightly coupled / depends on being placed into a specific context to work then it isn't a "control". You've violated the separation of concerns principle. As far as I can tell, this breaks any UserControl with a DependencyProperty. See nikolalukovic.com/programming/… and/or the answer by @jdawiz.
You usually start with a MainViewModel and assign that to your windows DataContext. From there you just populate everything. Sorry, something went wrong. This approach is called "state tree".
You can use the DataTemplateSelector to dynamically select a DataTemplate
at run time something along the lines of
public class TaskListDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate
SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement;
if (element != null && item != null && item is Task)
{
Task taskitem = item as Task;
if (taskitem.Priority == 1)
return
element.FindResource("importantTaskTemplate") as DataTemplate;
else
return
element.FindResource("myTaskTemplate") as DataTemplate;
}
return null;
}
}
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