Search code examples
c#uwpdatatemplate

Is it possible to update a DataTemplate in code?


Is there a way to update a DataTemplate in code?

I have a simple DataTemplate containing a single image. It's used for a 3rd party control's ContentTemplate property to represent the control's viewable image. (I have no control over this requirement.) Here's the DataTemplate's XAML definition with a generic "unknown" image:

    <DataTemplate x:Key="ControlImageDataTemplate">
        <Image Source="Assets/UnknownImage.png"/>
    </DataTemplate>

In my app, different control instances can have different images, and I don't know which image to use until run-time. So I need to update the DataTemplate image source at run-time in the code-behind. Ideally, I'd like to do something like this:

    // Update the DataTemplate
    ControlImageDataTemplate.Image.Source = new BitmapImage("Assets/RunTimeImage.png"); // CAN'T DO THIS!!!

    // Assign the updated DataTemplate to the control instance
    ThirdPartyControl.ContentTemplate = (DataTemplate)Resources["ControlImageDataTemplate"];

However, I have not been able to find a way to update a DataTemplate in code. Is this possible? Or is there an alternative?


Solution

  • As other users suggested in the comments, the perfect way to do this is with a DataTemplateSelector.

    First of all, you need to derive the DataTemplateSelector class, creating your own, and overriding the SelectTemplateCore method:

    public class SampleDataTemplateSelector : DataTemplateSelector
    {
        protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
        {
            if (item != null && container != null && <<item is a specific object>>)
            {
                // Put your logic code here in order to determine what case is the right one
                if (<<case 1>>) return SampleDataTemplate1;
                else if (<<case 2>>) return SampleDataTemplate2;
                //…
            }
        }
    }
    

    Then, put theese resources in your App.xaml (or into your Page's resources):

    <Application.Resources>
        <templateSelectorNamespace:SampleDataTemplateSelector x:Key="SampleTemplateSelector"/>
    
        <DataTemplate x:Key="SampleDataTemplate1">
            <Image Source="Assets/Image1.png"/>
        </DataTemplate>
        <DataTemplate x:Key="SampleDataTemplate2">
            <Image Source="Assets/Image2.png"/>
        </DataTemplate>
    </Application.Resources>
    

    Then, into your page, just use it with an ItemsControl derived control. Here's a way to use it, for example, in a ListView:

    <ListView ItemsSource="{x:Bind ViewModel.Elements, Mode=OneWay}" ItemTemplateSelector="{StaticResource SampleTemplateSelector}" HorizontalContentAlignment="Stretch"/>
    

    Best regards