Explicitly refresh DataTemplate from a DataTemplateSelector? Explicitly refresh DataTemplate from a DataTemplateSelector? wpf wpf

Explicitly refresh DataTemplate from a DataTemplateSelector?


Late to the party, I know. =)

When faced with this problem, I found it easiest to explicitly set a new TemplateSelector like

MyContentControl.ContentTemplateSelector =     new MyDataTemplateSelector();


I guess I am even later to the party, but for a different idea that may help someone...

You could also try using a ValueConverter on the ContentControls ContentTemplate property instead of a DataTemplateSelector.

Just have a property in your DataContext to bind, like ScreenNumber for example. Then in the ValueConverter return the DataTemplate that is associated with the ScreenNumber.

Example ValueConverter:

public class ValueDataTemplateConverter : IValueConverter{    public DataTemplate TemplateA { get; set; }    public DataTemplate TemplateB { get; set; }    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)    {        if (value is ValueType valueType)            switch (valueType)            {                case ValueType.TypeA:                    return TemplateA;                case ValueType.TypeB:                    return TemplateB;             }        return null;    }    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)    {        throw new NotImplementedException();    }}

Example xaml resource:

<converters:ValueDataTemplateConverter x:Key="ValueDataTemplateConverter">    <converters:ValueDataTemplateConverter.TemplateA>        <DataTemplate>            <TextBox Text="{Binding Value}" />        </DataTemplate>    </converters:ValueDataTemplateConverter.TemplateA>    <converters:ValueDataTemplateConverter.TemplateB>        <DataTemplate>            <CheckBox IsChecked="{Binding Value}" />        </DataTemplate>    </converters:ValueDataTemplateConverter.TemplateB></converters:ValueDataTemplateConverter>


I'm not aware of any (non-kludgy) way to do this: the DataTemplateSelector is called when WPF needs to select the template, and that's a one-off decision as far as WPF is concerned. (You can kludge it by making WPF think the content has changed, e.g. by setting the content to null and then back again -- I think that would work but haven't tested it -- but this is pretty ugly!) If there is a nice way to do this I too would be interested to know!

However, there is an alternative way to change how content is displayed that does update in response to data changes, and that is through triggers. You can use DataTriggers in your DataTemplate.Triggers collection to show and hide elements depending on the content data. To change the entire display, you could e.g. set up two renderings in a Grid, and use triggers to control which one is visible. You could even make your data template a ContentControl, and use a trigger to change the ContentTemplate. Of course this depends on the criteria for changing the template being bindable properties, which may not always be the case.

Here's some brief discussion of selectors vs. triggers, albeit in a slightly different context.