Приоритет свойства зависимостей WPF - шаблонный родитель - PullRequest
3 голосов
/ 20 ноября 2010

В списке источников значений свойств зависимостей вместе с относительным приоритетом локальное значение является наивысшим приоритетом для определения базового значения.
Сразу после локального значения находятся свойства шаблона изшаблонный родитель - например, родительский ControlTemplate для элемента управления, который был создан в контексте шаблона.

Мой вопрос такой: локальное значение указывается как имеющее приоритет над свойством шаблона, означает ли эточто значение свойства, заданное явно (локальное значение) для элемента управления, созданного в шаблоне, имеет приоритет над одним набором с триггером свойства в этом шаблоне?Кажется, это то, что подразумевают правила, но свойства, установленные с помощью триггеров в шаблоне элемента управления, как представляется, переопределяют (то есть имеют более высокий приоритет) локальные значения, установленные в шаблоне.ссылаются на значения, установленные только для элементов управления, НЕ созданных в шаблонах - и, следовательно, вы не можете реально сравнить приоритет между локальным значением и набором свойств с помощью триггера в шаблонном родительском элементе?

1 Ответ

4 голосов
/ 21 ноября 2010

Да, «локальное значение» в списке приоритетов относится только к свойствам, установленным для элементов вне шаблонов.Соответствующей частью списка приоритетов является 4b:

4. Свойства шаблона TemplatedParent .Элемент имеет TemplatedParent, если он был создан как часть шаблона (ControlTemplate или DataTemplate).Подробнее о том, когда это применимо, см. В разделе «TemplatedParent» далее в этом разделе.В шаблоне применяется следующий приоритет:

a.Триггеры из шаблона TemplatedParent.

b.Наборы свойств (обычно через атрибуты XAML) в шаблоне TemplatedParent.

Значения свойств, установленные в шаблоне, имеют более низкий приоритет, чем триггеры в шаблоне, и оба они имеют более низкий приоритет, чем локальные значения.

Чтобы узнать, как было установлено значение, вызовите DependencyPropertyHelper.GetValueSource и проверьте свойство BaseValueSource.Значения, установленные вне шаблона, будут иметь источник «Local», а значения внутри шаблона будут иметь источник «ParentTemplate».

Наличие их в качестве отдельных источников также означает, что система свойств может отслеживать локальное значение и значение родительского шаблона отдельно.Если вы установите локальное значение для свойства, которое имеет значение из шаблона, а затем вызовете ClearValue , оно вернется к значению, установленному шаблоном.


Вот пример, демонстрирующий локальное значение, переопределяющее значение из шаблона.Создайте UserControl с кодом ниже и добавьте его в окно.Он имеет синий прямоугольник, который меняется на зеленый, когда мышь находится над элементом управления.Если вы нажмете «Установить», код установит локальное значение в прямоугольнике, которое переопределит оба значения.Если вы нажмете «Очистить», он очистит локальное значение и восстановит значения из шаблона.Вы можете нажать «Показать», чтобы увидеть источник текущего значения (вам нужно нажать кнопку с клавиатурой, чтобы увидеть ParentTemplate, так как при наведении курсора на кнопку будет активирован триггер).

XAML:

<UserControl
    x:Class="WpfApplication1.UserControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Template>
        <ControlTemplate>
            <StackPanel Background="Transparent">
                <Button Click="Display_Click" Content="Display"/>
                <Button Click="Set_Click" Content="Set"/>
                <Button Click="Clear_Click" Content="Clear"/>
                <Rectangle Width="100" Height="100"
                           Fill="Blue" Name="PART_Rectangle"/>
            </StackPanel>
            <ControlTemplate.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter TargetName="PART_Rectangle"
                            Property="Fill" Value="Green"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </UserControl.Template>
</UserControl>

Код-позади:

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        rectangle = Template.FindName("PART_Rectangle", this) as Rectangle;
    }

    private Rectangle rectangle;

    private void Display_Click(object sender, RoutedEventArgs e)
    {
        var source = DependencyPropertyHelper.GetValueSource(
            rectangle, Rectangle.FillProperty);
        MessageBox.Show(string.Format("Value {0}; Source {1}",
            rectangle.Fill, source.BaseValueSource));
    }

    private void Set_Click(object sender, RoutedEventArgs e)
    {
        rectangle.Fill = Brushes.Red;
    }

    private void Clear_Click(object sender, RoutedEventArgs e)
    {
        rectangle.ClearValue(Rectangle.FillProperty);
    }
}
...