WPF中使用样式的下划线标签 [英] Underline Label in WPF, using styles

查看:259
本文介绍了WPF中使用样式的下划线标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的风格如下:

<Style x:Key="ActionLabelStyle" TargetType="{x:Type Label}">
    <Setter Property="Margin" Value="10,3" />
    <Setter Property="Padding" Value="0" />
    <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
    <Setter Property="FontFamily" Value="Calibri" />
    <Style.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsMouseOver" Value="True" />
                <Condition Property="IsEnabled" Value="True" />
            </MultiTrigger.Conditions>
            <Setter Property="Background" Value="Red" />
            <Setter Property="TextBlock.TextDecorations" Value="Underline" />
        </MultiTrigger>
    </Style.Triggers>
</Style>

因此,基本上,我希望有一个标签,该标签在启用后且鼠标光标位于其上时带有下划线.此样式无效的部分是<Setter Property="TextBlock.TextDecorations" Value="Underline" />.现在,我在这里做错了什么?感谢您的所有帮助.

So basically, I want to have a label which is underlined when it is enabled and the mouse cursor is over it. The part of this style which is not working is the <Setter Property="TextBlock.TextDecorations" Value="Underline" />. Now, what am I doing wrong here? Thanks for all the help.

推荐答案

这实际上比看起来要困难得多.在WPF中,标签不是TextBlock.它源自ContentControl,因此可以在其Content集合中托管其他非文本控件.

This is actually much more difficult than it appears. In WPF, a Label is not a TextBlock. It derives from ContentControl and can therefore host other, non-text controls in its Content collection.

但是,您可以指定一个字符串作为内容,如下例所示.在内部,将构造一个TextBlock来为您托管文本.

However, you can specify a string as the content as in the example below. Internally, a TextBlock will be constructed to host the text for you.

<Label Content="Test!"/>

这在内部翻译为:

    <Label>
        <Label.Content>
            <TextBlock>
                Test!
            </TextBlock>
        </Label.Content>
    </Label>

对此的简单解决方案是将TextBlock的TextDecorations属性作为附加属性.例如,FontSize是按这种方式设计的,因此可以进行以下工作:

The simple solution to this would be for the TextDecorations property of a TextBlock to be an attached property. For example, FontSize is designed this way, so the following works:

    <Label TextBlock.FontSize="24">
        <Label.Content>
            <TextBlock>
                Test!
            </TextBlock>
        </Label.Content>
    </Label>

附加的TextBlock.FontSize属性可以在可视树的任何位置应用,并将覆盖树中任何TextBlock后代的该属性的默认值.但是,TextDecorations属性不是以此方式设计的.

The TextBlock.FontSize attached property can be applied anywhere in the visual tree and will override the default value for that property on any TextBlock descendant in the tree. However, the TextDecorations property is not designed this way.

这至少给了您一些选择.

This leaves you with at least a few options.

  1. 使用颜色,边框,光标等代替带下划线的文本,因为它易于实现100%.
  2. 更改执行此操作的方式,以将样式应用于TextBlock.
  3. 麻烦创建您自己的附加财产以及遵守它的控制模板.
  4. 执行类似以下操作,以嵌套显示为您样式的子代的TextBlock样式:
  1. Use color, border, cursor, etc., instead of underlined text because this is 100% easier to implement.
  2. Change the way you are doing this to apply the Style to the TextBlock instead.
  3. Go to the trouble to create your own attached property and the control template to respect it.
  4. Do something like the following to nest the style for TextBlocks that appear as children of your style:

仅供参考,到目前为止,这是我在WPF中所做的最丑陋的事情,但这是可行的!

FYI, this is the ugliest thing I've done in WPF so far, but it works!

    <Style x:Key="ActionLabelStyle" TargetType="{x:Type Label}">
        <Setter Property="Margin" Value="10,3" />
        <Setter Property="Padding" Value="0" />
        <Setter Property="TextBlock.TextWrapping" Value="Wrap" />
        <Setter Property="FontFamily" Value="Calibri" />
        <Style.Triggers>
            <MultiTrigger>
                <MultiTrigger.Conditions>
                    <Condition Property="IsMouseOver" Value="True" />
                    <Condition Property="IsEnabled" Value="True" />
                </MultiTrigger.Conditions>
                <Setter Property="Background" Value="Red" />
            </MultiTrigger>
        </Style.Triggers>
        <Style.Resources>
            <Style TargetType="TextBlock">
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Label}, Path=IsMouseOver}" Value="True" />
                            <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsEnabled}" Value="True" />
                        </MultiDataTrigger.Conditions>
                        <Setter Property="TextDecorations" Value="Underline"/>
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </Style.Resources>
    </Style>

之所以起作用,是因为它覆盖了此样式的标签下的任何TextBlock的默认样式.然后,它使用MultiDataTrigger允许相对绑定返回到Label,以检查其IsMouseOver属性是否为True. uck.

This works because it is overriding the default style of any TextBlock beneath a Label of this style. It then uses a MultiDataTrigger to allow relative binding back up to the Label to check if its IsMouseOver property is True. Yuck.

请注意,这仅在您显式创建TextBlock时有效.发布此邮件时我不正确,因为我已经弄脏了测试标签.嘘感谢Anvaka,指出了这一点.

Note that this only works if you explicitly create the TextBlock. I was incorrect when I posted this because I had already dirtied up my test Label. Boo. Thanks, Anvaka, for pointing this out.

    <Label Style="{StaticResource ActionLabelStyle}">
        <TextBlock>Test!</TextBlock>
    </Label>

这行得通,但是如果您不得不麻烦一下,那就太辛苦了.要么有人会发布一些更聪明的东西,要么正如您所说,我的选择1现在看起来还不错.

This works, but if you have to go to this trouble, you're just working too hard. Either someone will post something more clever, or as you said, my option 1 is looking pretty good right now.

这篇关于WPF中使用样式的下划线标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆