Switching DataTemplates dynamically in WPF

January 26th, 2009

I spent a couple of days last week writing a (very) simple Sudoku solver in WPF. For the most part, everything I wanted to do was ridiculously easy to achieve with WPF. However, there was one point that took me an hour or two of research to figure out: switching DataTemplates dynamically.

To draw my Sudoku board, I data bind to some model-objects that describe the board. Each cell on the board has a value (a nullable int), and a list of values that could possibly go in that cell. The effect I wanted to achieve was to show the value for a cell if it’s not null, and show a grid of possible values if not yet determined:

Example of Desired Dynamic DataTemplate Effect

I finally found the answer in a comment by Andy Kutruff on a post asking a very similar question to mine . There’s a minor skirmish in the comments about whether or not Andy’s solution is injecting business logic into the presentation layer, but I feel that his solution is the correct one for this application because the two templates are purely a UI concern, and not related to the functioning of the model.

The basic idea is to use a DataTemplate containing a single ContentPresenter as a selector. The ContentPresenter has a ContentTemplate set on it that becomes the default template. Data triggers on the template are then used to switch between the various sub-templates for the ContentPresenter. The following are reformatted excerpts from the XAML code for my sudoku solver. To see the full source code for the project, look at the code page. Please excuse the lack of syntax highlighting for XAML; I need to figure out something for that.

To start, we need to make a DataTemplate that is used by the control in question. This template simply contains a ContentControl whose contents will be swapped out based on data.

<DataTemplate x:Key="CellTemplate">
    <ContentControl 
        ContentTemplate="{StaticResource CellSelectorTemplate}" 
        Content="{Binding}" />
</DataTemplate>

Finally, we create the template that does the selecting of sub-templates. This works by using data triggers to change the ContentPresenter’s ContentTemplate.

<DataTemplate x:Key="CellSelectorTemplate">
    <ContentPresenter x:Name="Presenter"
        ContentTemplate="{StaticResource CellWithValueTemplate}"
        Content="{TemplateBinding Content}" />
 
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Value}" Value="{x:Null}">
            <Setter TargetName="Presenter"
                Property="ContentTemplate"
                Value="{StaticResource CellWithoutValueTemplate}" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

After that, it’s just creating the templates for each of the states needed. The data trigger switches between the templates depending on the data, and the templates do their magic.

Comments

  1. Pallavi - December 24th, 2009 @ 2:24 am

    Hey really thanks, very good solution you have given in blog.
    I was having problem to display combobox of wpf as below:
    Default value should be blank, and other values should be displayed in format “Code – Description” Both fields are of class XYZ.
    I solved that using your solution as below:

    ;
    ;
    ;
    ;

    This resolves my requirement. Thanks a lot.

  2. Pallavi_again - December 24th, 2009 @ 2:27 am

    Hey really thanks, very good solution you have given in blog.
    I was having problem to display combobox of wpf as below:
    Default value should be blank, and other values should be displayed in format “Code – Description” Both fields are of class XYZ.
    I solved that using your solution as below:

    ;
    ;

    This resolves my requirement. Thanks a lot.

Leave a Comment