Let’s say that you want to create your UI but in a dynamic way. Imagine a view which is based on a list of items you want to display. But this list can vary (depending on rights, or context). In this simple example, we want a label with a textbox, then a checkbox. We can do that with a TemplateSelector .

This is the final result; a simple list of settings with name and value.

First we need a model;

using Prism.Mvvm; namespace DataTemplateSelectorDemo.Models { public enum MySettingType { Boolean, String } public class MySetting : BindableBase { private string _name; public string Name { get { return _name; } set { SetProperty(ref _name, value); } } private string _stringValue; public string StringValue { get { return _stringValue; } set { SetProperty(ref _stringValue, value); } } private bool _boolValue; public bool BoolValue { get { return _boolValue; } set { SetProperty(ref _boolValue, value); } } private MySettingType _type; public MySettingType Type { get { return _type; } set { SetProperty(ref _type, value); } } public override string ToString() { return $"{Name} - {StringValue}"; } } }
Code language: C# (cs)

As you can see, there is a field named Type. This enum will determine which template we want to choose in the DataTemplateSelector

Now we can create the SettingTemplateSelector, a class inheriting from DataTemplateSelector. This class allows you to define two templates in your XAML StringTemplate (textbox) and BooleanTemplate (checkbox).

using DataTemplateSelectorDemo.Models; using System.Windows; using System.Windows.Controls; namespace DataTemplateSelectorDemo.Helpers { public class SettingTemplateSelector : DataTemplateSelector { public DataTemplate StringTemplate { get; set; } public DataTemplate BooleanTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { var selectedTemplate = this.StringTemplate; var setting = item as MySetting; if (setting == null) return selectedTemplate; switch (setting.Type) { case MySettingType.String: selectedTemplate = this.StringTemplate; break; case MySettingType.Boolean: selectedTemplate = this.BooleanTemplate; break; } return selectedTemplate; } } }
Code language: C# (cs)

You only need to declare in the ViewModel a list of settings and to initialize it.

using DataTemplateSelectorDemo.Models; using Prism.Mvvm; using System.Collections.Generic; namespace DataTemplateSelectorDemo.ViewModels { public class MainWindowViewModel : BindableBase { #region Properties private string _title = "DataTemplateSelector Demo"; public string Title { get { return _title; } set { SetProperty(ref _title, value); } } private List<MySetting> _settings; public List<MySetting> Settings { get { return _settings; } set { SetProperty(ref _settings, value); } } #endregion public MainWindowViewModel() { this.LoadSettings(); } private void LoadSettings() { this.Settings = new List<MySetting> { new MySetting { Name = "Setting1", StringValue = "here is the string", Type = MySettingType.String }, new MySetting { Name = "Setting2", BoolValue = true, Type = MySettingType.Boolean }, }; } } }
Code language: C# (cs)

Finally, we can use an ItemsControl binded to the list of settings to display. By setting the ItemTemplateSelector to our custom one, the correct template (BooleanTemplate or StringTemplate) will be selected automatically.

<Window x:Class="DataTemplateSelectorDemo.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" xmlns:helpers="clr-namespace:DataTemplateSelectorDemo.Helpers" Title="{Binding Title}" Height="350" Width="525"> <Window.Resources> <!--BOOL TEMPLATE--> <DataTemplate x:Key="BooleanTemplate"> <StackPanel Orientation="Horizontal" Margin="10"> <TextBlock Text="{Binding Name}"></TextBlock> <CheckBox IsChecked="{Binding BoolValue}" Margin="5, 0, 0, 0"/> </StackPanel> </DataTemplate> <!--STRING TEMPLATE--> <DataTemplate x:Key="StringTemplate"> <StackPanel Orientation="Horizontal" Margin="10"> <TextBlock Text="{Binding Name}"/> <TextBox Width="100" Text="{Binding StringValue}" Margin="5, 0, 0, 0"/> </StackPanel> </DataTemplate> <helpers:SettingTemplateSelector x:Key="SettingTemplateSelector" BooleanTemplate="{StaticResource BooleanTemplate}" StringTemplate="{StaticResource StringTemplate}"/> </Window.Resources> <Grid Margin="10"> <!--OUR LIST OF SETTINGS TO DISPLAY--> <ItemsControl ItemsSource="{Binding Settings}" ItemTemplateSelector="{StaticResource SettingTemplateSelector}"> </ItemsControl> </Grid> </Window>
Code language: HTML, XML (xml)

Happy coding!  🙂