A few days ago we needed to allow selection of text in some of the fields in a read-only screen. This was required in order to apply copy and paste capabilities to those fields. About all of the fields on screen were shown using TextBlocks, which, as you may know, don’t allow selection of Text.
So after investigating this matter, we decided to replace all TextBlocks in fields that needed selection to TextBoxes with modified properties (no border, no tab stop, read only). We did have performance in mind, but could not think of a better solution. The solution looked something like this:
<TextBox Text="Hello"
IsReadOnly="True"
IsTabStop="False"
BorderThickness="0"
/>
But then a colleague of mine referenced me to this nice article about TextBoxes performance. Although the article writer and I did not share the same requirements, it did give me an idea of how to implement a solution with better performance. The idea was to change the TextBox template to host a simple TextBlock as long as the mouse cursor is not over the TextBox. Once the cursor moves over the TextBox, the template changes back to the default one. So now it looks like this:
<TextBox Text="Hello"
IsReadOnly="True"
IsTabStop="False"
BorderThickness="0"
>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="IsFocused" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<TextBlock Text="{TemplateBinding Text}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</MultiTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
This improves performance a lot, especially if you have quite a few of these controls spread around the screen. Using our dear friend Snoop, it’s very nice to see that the tree size changes from 10 (the original tree size of a TextBox) to 1:
Cursor not over
Cursor over

I'm still having issues with the layout of the different templates. Right now the text kinda jumps when the cursor goes over i, probably because of the complex layout of the default TextBox template. I did not find a way to make it work properly in all scenarios, if anybody got an idea that would be great!