Один подход выхода должен вывести его на печать к холсту! Потяните каждый прямоугольник с помощью полупрозрачного цвета. Время выполнения.NET будет делать рисунок в оптимизированном, собственном коде - или даже использование аппаратного акселератора.
Затем у Вас есть к чтению назад пиксели. Действительно ли каждый пиксель является цветом фона, прямоугольным цветом или другим цветом? Единственным путем это может быть другой цвет, то, если два или больше перекрытые прямоугольника...
, Если бы это - слишком много обмана, я рекомендовал бы дерево квадрантов, как другая отвечающая сторона сделала, или r-дерево .
На самом деле это намного сложнее, чем кажется. В WPF метка не является TextBlock. Он является производным от ContentControl и, следовательно, может содержать другие нетекстовые элементы управления в своей коллекции Content.
Однако вы можете указать строку в качестве содержимого, как в примере ниже. Внутри будет создан 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 разработано иначе.
Это оставляет вам, по крайней мере, несколько вариантов.
К вашему сведению, это самая уродливая вещь, которую я делал в 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. Уф.
Править:
Обратите внимание, что это работает, только если вы явно создаете TextBlock. Я был неправ, когда разместил это, потому что я уже испачкал свой тестовый ярлык. Бу. Спасибо, Анвака, за указание на это.
<Label Style="{StaticResource ActionLabelStyle}">
<TextBlock>Test!</TextBlock>
</Label>
Это работает, но если вам придется столкнуться с этой проблемой, вы просто слишком много работаете. Либо кто-то опубликует что-нибудь более умное, либо, как вы сказали, мой вариант 1 сейчас выглядит неплохо.
Я думаю, проблема в том, что TextBlock.TextDecorations
является не определено в Label
.
Вы можете использовать этот подход , если вам нравится использовать TextBlock
, а не Label
.
В дополнение к ответу Джерри, чтобы избежать необходимости добавлять TextBlock в шаблон каждый раз, вы можете позволить стилю делать это тоже, добавив свойство Setter в стиль:
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Label}">
<TextBlock>
<ContentPresenter />
</TextBlock>
</ControlTemplate>
</Setter.Value>
</Setter>
Затем ваш ярлык вернулся к:
<Label Content="Test!" Style="{StaticResource ActionLabelStyle}" />
Спасибо, Джерри!
Эндрю.