Маркировка подчеркивания в WPF, с помощью стилей

Один подход выхода должен вывести его на печать к холсту! Потяните каждый прямоугольник с помощью полупрозрачного цвета. Время выполнения.NET будет делать рисунок в оптимизированном, собственном коде - или даже использование аппаратного акселератора.

Затем у Вас есть к чтению назад пиксели. Действительно ли каждый пиксель является цветом фона, прямоугольным цветом или другим цветом? Единственным путем это может быть другой цвет, то, если два или больше перекрытые прямоугольника...

, Если бы это - слишком много обмана, я рекомендовал бы дерево квадрантов, как другая отвечающая сторона сделала, или r-дерево .

11
задан Dave Clemmer 18 August 2011 в 01:14
поделиться

3 ответа

На самом деле это намного сложнее, чем кажется. В 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 разработано иначе.

Это оставляет вам, по крайней мере, несколько вариантов.

  1. Используйте цвет, рамку, курсор и т. Д. Вместо подчеркнутого текста, потому что это на 100% легче реализовать.
  2. Измените способ, которым вы это делаете, на вместо этого примените стиль к текстовому блоку.
  3. Создайте свое собственное присоединенное свойство и шаблон элемента управления для его соблюдения.
  4. Сделайте что-то вроде следующего, чтобы вложить стиль для текстовых блоков, которые отображаются как дочерние элементы вашего стиля:

К вашему сведению, это самая уродливая вещь, которую я делал в 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 сейчас выглядит неплохо.

23
ответ дан 3 December 2019 в 02:52
поделиться

Я думаю, проблема в том, что TextBlock.TextDecorations является не определено в Label .

Вы можете использовать этот подход , если вам нравится использовать TextBlock , а не Label .

3
ответ дан 3 December 2019 в 02:52
поделиться

В дополнение к ответу Джерри, чтобы избежать необходимости добавлять 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}" />

Спасибо, Джерри!

Эндрю.

4
ответ дан 3 December 2019 в 02:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: