Do not override DataTemplate for System.String
Default template for System.String
is used whenever you create a control with Content of type String
. E.g.
<Label Content="foo" />
or
<Label>foo</Label>
.
Overriding it may look like a good idea in some cases, but it causes bad side effects. Don't do that.
<!-- Danger! Do not do this at home! --> <DataTemplate DataType="{x:Type system:String}"> <TextBlock Text="{Binding}" /> </DataTemplate>
Here's a set of labels rendered with and without string data template override:
The labels come from the following XAML:
<StackPanel Orientation="Vertical"> <Label>Normal Text</Label> <Label>Access _Text</Label> <Label ContentStringFormat="Formatted {0}">Text</Label> <Label ContentStringFormat="Formatted Access {0}">_Text</Label> </StackPanel>
The overriden template does not convert underscores to keyboard shortucts, and does not respect ContentStringFormat
.
This is because ContentPresenter
class (ContentPresenter.cs)
uses not one, but four different templates to render strings: StringContentTemplate
, AccessTextContentTemplate
,
FormattingStringContentTemplate
and FormattingAccessTextContentTemplate
. AccessText
is a less famous
brother of TextBlock
that converts underscores into keyboard shortcuts.
How did I find out about this? The hard way. I was looking to the solution to the implicit TextBlock style overriding all TextBlocks in the application. In this StackOverflow question the answer suggests to override data template for String, and I followed it. In a couple of days QA told me that now we have underscores in the text of most of our buttons, so I had to issue an emergency fix. As they say, smart people learn from the mistakes of others. Less smart people learn from their own mistakes.
Feedback
Questions? Comments?
Drop me a line
Copyright (c) Ivan Krivyakov. Last updated: October 28, 2014