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!  🙂