Here is a simple example about the ContentControl and the TemplateSelector. This is really useful when you have a single model that can be represented on the UI in different ways depending on an enum for example.
This will be the final result in the UI while using the same model:
Let’s start with our model:
namespace Wpf_ContentControl.Models
{
public class MyModel
{
public ControlType ControlType { get; set; }
public string Content { get; set; }
}
public enum ControlType
{
Header,
Value
}
}
Code language: C# (cs)
Now, let’s design our template selector, where the selection will be based on the enum from our model:
using System.Windows;
using System.Windows.Controls;
using Wpf_ContentControl.Models;
namespace Wpf_ContentControl.Helpers
{
public class MyTemplateSelector : DataTemplateSelector
{
public DataTemplate HeaderTemplate { get; set; }
public DataTemplate ValueTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var selectedTemplate = ValueTemplate;
if (!(item is MyModel model))
return selectedTemplate;
switch (model.ControlType)
{
case ControlType.Header:
selectedTemplate = HeaderTemplate;
break;
case ControlType.Value:
selectedTemplate = ValueTemplate;
break;
}
return selectedTemplate;
}
}
}
Code language: C# (cs)
Let’s instanciate our model as a Header and a Value in the MainViewModel:
using Prism.Mvvm;
using Wpf_ContentControl.Models;
namespace Wpf_ContentControl
{
public class MainVM : BindableBase
{
private MyModel _header;
public MyModel Header
{
get { return _header; }
set { SetProperty(ref _header, value); }
}
private MyModel _value;
public MyModel Value
{
get { return _value; }
set { SetProperty(ref _value, value); }
}
public MainVM()
{
Header = new MyModel
{
ControlType = ControlType.Header,
Content = "Header"
};
Value = new MyModel
{
ControlType = ControlType.Value,
Content = "Value"
};
}
}
}
Code language: C# (cs)
Last but not least, our View containing the ContentControl for our Header and Value:
<Window x:Class="Wpf_ContentControl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:helpers="clr-namespace:Wpf_ContentControl.Helpers"
mc:Ignorable="d"
Title="ContentControl Demo" Height="150" Width="200">
<Window.Resources>
<DataTemplate x:Key="HeaderTemplate">
<TextBlock VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
TextAlignment="Center"
FontWeight="Bold"
FontSize="15"
Background="LightGray"
Width="70"
Text="{Binding Content}" />
</DataTemplate>
<DataTemplate x:Key="ValueTemplate">
<Border BorderBrush="LightGray"
BorderThickness="1"
Width="70"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch">
<TextBlock VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
TextAlignment="Center"
Width="70"
Text="{Binding Content}" />
</Border>
</DataTemplate>
<helpers:MyTemplateSelector
x:Key="ValueTemplateSelector"
HeaderTemplate="{StaticResource HeaderTemplate}"
ValueTemplate="{StaticResource ValueTemplate}"/>
</Window.Resources>
<StackPanel Margin="10">
<ContentControl
Content="{Binding Header}"
ContentTemplateSelector="{StaticResource ValueTemplateSelector}">
</ContentControl>
<ContentControl
Content="{Binding Value}"
ContentTemplateSelector="{StaticResource ValueTemplateSelector}">
</ContentControl>
</StackPanel>
</Window>
Code language: HTML, XML (xml)
If you want more examples about TemplateSelector, have a look my other post about ItemsControl here.
Happy coding! 😉