样式化ContentControl

Jef*_*eff 3 .net wpf xaml

我有一个自定义WPF控件.它有一个嵌套的ContentControl,它绑定到模板的Content属性,因此它可以将任何对象设置为其内容.

如果内容是原始字符串,我想将以下样式应用于TextBlock(我知道当实际呈现Visual Tree时,如果将ContentControl的Content属性设置为字符串,则会生成带有TextBlock的ContentPresenter).

<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>
Run Code Online (Sandbox Code Playgroud)

我本以为这样做的方法是通过嵌套资源(这是我的自定义控件的一部分):

<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>
Run Code Online (Sandbox Code Playgroud)

所以...上面说的(对我来说)如果ContentControl以嵌套的TextBlock结束,我们应该应用Label样式,对吗?...但不是,在上面的例子中没有应用Label样式.

我怎么能做到这一点?

谢谢.

Fre*_*lad 5

更新

有关为何TextBlock未应用创建的样式的说明,请参阅此链接上的答案5:WPF中的文本块样式覆盖标签样式

这是因为ContentPresenter为字符串内容创建了一个TextBlock,并且由于该TextBlock不在可视树中,因此它将查找到Appliacton级别资源.如果您在Appliaction级别为TextBlock设置样式,那么它将应用于ControlControls中的这些TextBlock.

你可以用一个 DataTemplateSelector

<DataTemplate x:Key="stringTemplate">
    <TextBlock Style="{StaticResource Label}"/>
</DataTemplate>
<local:TypeTemplateSelector x:Key="TypeTemplateSelector"
                            StringTemplate="{StaticResource stringTemplate}" />

<ContentControl ContentTemplateSelector="{StaticResource TypeTemplateSelector}"
                ...>
Run Code Online (Sandbox Code Playgroud)

TypeTemplateSelector示例

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

您还必须绑定Text属性 TextBlock

<Style x:Key="Label" TargetType="TextBlock">
    <Setter Property="Text" Value="{Binding}"/>
    <!-- Additional setters.. -->
</Style>
Run Code Online (Sandbox Code Playgroud)