views:

29

answers:

1

I have a general question about WPF performance. We have a relatively simple forms application. Some team members believe that redesigning the templates for basic controls will improve performance and maintainability. One preferred technique is to create multiple control templates for a control, and swap them out with triggers. The belief is that a smaller visual tree will be more performant.

For example, the checkbox template is now two templates, one checked and one unchecked:

    <ControlTemplate x:Key="CheckedCheckBoxCT" TargetType="{x:Type CheckBox}">
    <Grid x:Name="gLayoutRoot" VerticalAlignment="Center" HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="colCheck" />
            <ColumnDefinition x:Name="colContentLabel" />
        </Grid.ColumnDefinitions>
        <Rectangle x:Name="rectOuter" 
                Stroke="{TemplateBinding BorderBrush}" 
                StrokeThickness="0.5" 
                Fill="White" 
                Width="13" Height="13"   />
        <Rectangle x:Name="rectInner" 
                Stroke="{TemplateBinding OpacityMask}" 
                StrokeThickness="0.5" 
                Width="9" Height="9" 
                Fill="{TemplateBinding Background}"/>
        <Path x:Name="CheckMark"                
                  Data="{DynamicResource CheckSymbol}" 
                  Fill="{TemplateBinding Foreground}"/>
        <ContentPresenter x:Name="cpContent" />
    </Grid>
</ControlTemplate>

and then the unchecked (note there's no path element):

    <ControlTemplate x:Key="CheckBoxCT" TargetType="{x:Type CheckBox}">
    <Grid x:Name="gLayoutRoot" 
           VerticalAlignment="Center" 
          HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="colCheck" />
            <ColumnDefinition x:Name="colContentLabel" />
        </Grid.ColumnDefinitions>
        <Rectangle x:Name="rectOuter" 
                   Stroke="{TemplateBinding BorderBrush}" 
                   StrokeThickness="0.5" 
                   Fill="White" 
                   Width="13" Height="13"   />
        <Rectangle x:Name="rectInner" 
                   Stroke="{TemplateBinding OpacityMask}" 
                   StrokeThickness="0.5" 
                   Fill="{TemplateBinding Background}" 
                   Width="9" Height="9" />
        <ContentPresenter x:Name="cpContent" 
                    Margin="5,0,0,0" 
                    VerticalAlignment="Center" 
                    Grid.Column="1" />
    </Grid>
</ControlTemplate>

There is a similar discussion on making a read-only textbox with selectable text, using triggers to swap out a textblock (that you can't select text from) with a textbox.

Does this really improve performance to any appreciable degree? With the checkbox, would a trigger to show/hide the check, instead of two different control templates, be about the same, or better?

I really don't care, but it seems like there's a lot of complexity added for not much gain. I was curious what others' opinions were, esp. if based on objective experience. (You can see I don't care enough to set up some sample apps and test performance on them. :) )

Thanks!

A: 

Here is a blog post discussing performance issues with regards to Visual Studio, they mention that simplifying the visual tree was not something they looked into much. In your example I think having two templates for a checkbox would hinder rather than improve maintainability as modifying the look will require changes to both. Also switching the template when clicking is likely to be slower than adjusting the visibility of an element.

With regards to overall performance I would pay more attention to Effects, VisualBrushes e.t.c but simplifying Templates used a lot (ItemTemplates) can be worthwhile, if the situation with the read only textbox is in an ItemControl with lots of elements and most would be disabled I would be inclined to do it. There are quite a few resources about WPF performance including some mentioned in that post.

Kris