当内容为字符串时,在Silverlight中为ContentPresenter创建的隐式文本块下划线?

当内容为字符串时,在Silverlight中为ContentPresenter创建的隐式文本块下划线?,silverlight,xaml,contentpresenter,Silverlight,Xaml,Contentpresenter,我正在尝试为内容控件(如按钮或HeaderedContentControl等)创建一个模板,其中文本带有下划线 当指定了Content=“此文本带下划线”时,我只想给文本加下划线 如果内容是另一个UIElement,它必须继续正常工作 大多数提出相同问题的帖子都对修改模板,使其仅适用于作为内容的字符串感到满意。Scott Gu有一篇关于这个问题的好文章,但没有提到这个问题 如果您实际将Content作为类型TextBlock的实例传入,而不是作为字符串传入,则以下示例将起作用。当然,可视化树有一

我正在尝试为内容控件(如按钮或HeaderedContentControl等)创建一个模板,其中文本带有下划线

当指定了
Content=“此文本带下划线”
时,我只想给文本加下划线

如果内容是另一个UIElement,它必须继续正常工作

大多数提出相同问题的帖子都对修改模板,使其仅适用于作为内容的字符串感到满意。Scott Gu有一篇关于这个问题的好文章,但没有提到这个问题

如果您实际将
Content
作为类型
TextBlock
的实例传入,而不是作为字符串传入,则以下示例将起作用。当然,可视化树有一个文本块,所以它应该设置它的样式。也许这是Sivlerlight的局限性

这个例子显示了黑色文本和红色大文本,当我希望它们都显示为红色大文本时

    <navigation:Page.Resources>
    <Style TargetType="TextBlock" x:Key="style123">
        <Setter Property="Foreground"  Value="Red"/>
        <Setter Property="FontSize" Value="72"/>
        <Setter Property="FontWeight" Value="Bold"/>
        <Setter Property="TextDecorations" Value="Underline"/>
    </Style>
</navigation:Page.Resources>

<StackPanel>        

    <!-- This doesn't work and shows black text -->
    <ContentPresenter Content="Small black text">
        <ContentPresenter.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource style123}"/>
        </ContentPresenter.Resources>
    </ContentPresenter>

    <!-- This works and shows red text -->
    <ContentPresenter>
        <ContentPresenter.Content>
            <TextBlock Text="This is big red text"/>
        </ContentPresenter.Content>

        <ContentPresenter.Resources>
            <Style TargetType="TextBlock" BasedOn="{StaticResource style123}"/>
        </ContentPresenter.Resources>
    </ContentPresenter>

</StackPanel>

您可以将正在使用的任何实际
ContentControl
(即
按钮
)子类化,并覆盖
OnContentChanged
,以便在新内容为字符串时将
Content
属性重置为带下划线的
文本块
。如果newContent不是字符串,它将以通常的方式执行

public类下划线按钮:按钮
{
受保护的覆盖无效OnContentChanged(对象oldContent、对象newContent)
{
if(newContent是字符串)
{
TextBlock TextBlock=新的TextBlock();
Text=newContent作为字符串;
textBlock.textEditions=textEditions.Underline;
this.Content=textBlock;
}
base.OnContentChanged(旧内容、新内容);
}
}

仅仅为了实现这一点而对其进行子类化有点烦人,但它避免了混乱的样式模板和子类化
ContentPresenter

,您可以对任何实际的
ContentControl
(即
按钮
)进行子类化如果新内容是字符串,您正在使用并覆盖
OnContentChanged
,以便将
Content
属性重置为带下划线的
TextBlock
。如果newContent不是字符串,它将以通常的方式执行

public类下划线按钮:按钮
{
受保护的覆盖无效OnContentChanged(对象oldContent、对象newContent)
{
if(newContent是字符串)
{
TextBlock TextBlock=新的TextBlock();
Text=newContent作为字符串;
textBlock.textEditions=textEditions.Underline;
this.Content=textBlock;
}
base.OnContentChanged(旧内容、新内容);
}
}

仅仅为了完成这一点而进行子类化有点烦人,但它避免了混乱的样式模板和子类化
ContentPresenter

尝试以下示例,使用DataTemplate自定义呈现
string
内容(我刚刚将背景设置为红色):



编辑:请注意,如果您需要更好的可重用性,您可以将其拉入
ContentControl
样式,而不是每次内联应用它…

尝试此示例,使用DataTemplate自定义呈现
string
内容(我刚刚将背景设置为红色):



编辑:请注意,如果您需要更好的可重用性,您可以将其拉到
ContentControl
样式中,而不是每次内联应用它…

PS。如果解决方案是像子类化ContentPresenter和拦截事件之类的疯狂问题,我很好。嗯,我刚刚意识到这可能会奏效……WPF中很少需要疯狂的解决方案——请看我的答案;-)另外,如果解决方案是像子类化ContentPresenter和拦截事件之类的疯狂的事情,我很好。嗯,我刚刚意识到这可能会奏效……WPF中很少需要疯狂的解决方案——请看我的答案;-)我以前确实尝试过让类似的东西工作,但无法让它与silverlight一起工作。我知道这是WPF,因为在silverlight中,我们甚至没有文本块的背景-(我以前确实尝试过让类似的东西工作,但无法让它与silverlight一起工作。我知道这是WPF,因为在silverlight中,我们甚至没有文本块的背景!:-(谢谢!这不需要成为base.OCC()的其他条件吗)?我不这么认为,您总是希望通知基础控件内容更改。如果新内容是字符串,您只是“跳入”并首先切换出实际内容。啊,没错……这是OnContentChanged,而不是OnContentChanged(可能实际上不会退出-我没有检查)。看起来此解决方案目前最适合Silverlight!谢谢!这不需要成为base.OCC()的另一个条件吗?我不这么认为,您总是希望将内容更改通知base控件。如果newContent是字符串,则您只是“跳入”然后首先切换实际内容。啊,没错……这是OnContentChanged,而不是OnContentChanged(它可能不会实际退出-我没有检查)。看起来这个解决方案现在最适合Silverlight!
<ContentControl Content="{Binding YourData}" >
  <ContentControl.Resources>
    <DataTemplate DataType="{x:Type s:String}">
      <TextBlock Text="{Binding}" Background="Red" />
    </DataTemplate>
  </ContentControl.Resources>
</ContentControl>