Reputation: 36573
I have a custom WPF control. It has a nested ContentControl which is bound to the template's Content property, so it can have any object set as its content.
IF the content is a raw string, I want to apply the following style to the TextBlock (I know that when the Visual Tree is actually rendered a ContentPresenter with a TextBlock is generated if you set a ContentControl's Content property to a string).
<Style x:Key="Label" TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Foreground">
<Setter.Value>
<SolidColorBrush>
<SolidColorBrush.Color>
<Color A="255" R="82" G="105" B="146" />
</SolidColorBrush.Color>
</SolidColorBrush>
</Setter.Value>
</Setter>
</Style>
I would have thought the way to do this was via nested resources (this is part of my custom control):
<ContentControl x:Name="SomeText" Margin="10,10,10,0"
Content="{TemplateBinding Content}"
IsTabStop="False" Grid.Column="1">
<ContentControl.Resources>
<Style TargetType="TextBlock" BasedOn="{StaticResource Label}" />
</ContentControl.Resources>
</ContentControl>
So...the above says (to me) if the ContentControl ends up with a nested TextBlock, we should apply the Label style, right?...but no, the Label style is not applied in the example above.
How can I accomplish this?
Thanks.
Upvotes: 3
Views: 1979
Reputation: 84656
Update
For an explanation of why the Style for the created TextBlock
isn't getting applied, see answer 5 at this link: Textblock style override label style in WPF
This is because ContentPresenter creates a TextBlock for a string content, and since that TextBlock isn't in the visual tree, it will lookup to Appliacton level resource. And if you difine a style for TextBlock at Appliaction level, then it will be applied to these TextBlock within ControlControls.
You could use a DataTemplateSelector
<DataTemplate x:Key="stringTemplate">
<TextBlock Style="{StaticResource Label}"/>
</DataTemplate>
<local:TypeTemplateSelector x:Key="TypeTemplateSelector"
StringTemplate="{StaticResource stringTemplate}" />
<ContentControl ContentTemplateSelector="{StaticResource TypeTemplateSelector}"
...>
TypeTemplateSelector example
public class TypeTemplateSelector : DataTemplateSelector
{
public DataTemplate StringTemplate { get; set; }
public override System.Windows.DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item is string)
{
return StringTemplate;
}
return base.SelectTemplate(item, container);
}
}
You'll also have to Bind the Text property for the TextBlock
<Style x:Key="Label" TargetType="TextBlock">
<Setter Property="Text" Value="{Binding}"/>
<!-- Additional setters.. -->
</Style>
Upvotes: 5