Ответ 1
Это намного сложнее, чем кажется. В WPF метка не является TextBlock. Он происходит из ContentControl и поэтому может размещать другие, нетекстовые элементы управления в его коллекции содержимого.
Однако вы можете указать строку как содержимое, как в приведенном ниже примере. Внутренне, TextBlock будет построен для размещения текста для вас.
<Label Content="Test!"/>
Это внутренне переводит на:
<Label>
<Label.Content>
<TextBlock>
Test!
</TextBlock>
</Label.Content>
</Label>
Простым решением для этого было бы свойство TextDecorations TextBlock быть присоединенным свойством. Например, FontSize разработан таким образом, поэтому следующие работы:
<Label TextBlock.FontSize="24">
<Label.Content>
<TextBlock>
Test!
</TextBlock>
</Label.Content>
</Label>
Вложенное свойство TextBlock.FontSize можно применять в любом месте визуального дерева и переопределить значение по умолчанию для этого свойства для любого потомка TextBlock в дереве. Однако свойство TextDecorations не создано таким образом.
Это оставляет вам хотя бы несколько вариантов.
- Используйте цвет, границу, курсор и т.д. вместо подчеркнутого текста, потому что это на 100% проще реализовать.
- Измените способ, которым вы это делаете, чтобы применить стиль к TextBlock вместо этого.
- Постарайтесь создать ваше собственное прикрепленное свойство и шаблон управления, чтобы его уважать.
- Сделайте что-то вроде следующего, чтобы вложить стиль для TextBlocks, которые отображаются как дети вашего стиля:
FYI, это самая уродливая вещь, которую я сделал в 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" />
</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, чтобы разрешить относительную привязку к ярлыку, чтобы проверить, является ли его свойство IsMouseOver True. Тьфу.
Edit:
Обратите внимание, что это работает, только если вы явно создаете TextBlock. Я был некорректным, когда я разместил это, потому что я уже загрязнил свой тестовый ярлык. Бу. Спасибо, Анвака, за это.
<Label Style="{StaticResource ActionLabelStyle}">
<TextBlock>Test!</TextBlock>
</Label>
Это работает, но если вам нужно идти на эту проблему, вы просто слишком много работаете. Либо кто-то опубликует что-то более умное, или, как вы сказали, мой вариант 1 выглядит довольно хорошо прямо сейчас.