是的,优先列表中的“本地值”仅指在模板之外的元素上设置的属性。优先级列表的相关部分是4b:
4。 TemplatedParent 模板属性。一个元素有一个
TemplatedParent 如果它被创建为
模板的一部分(一个 ControlTemplate
或数据模板)。有关何时的详细信息
这适用,请参阅 TemplatedParent
稍后在本主题中。内
模板,以下优先级
适用:
一个。来自 TemplatedParent 的触发器
模板。
b.属性集(通常通过
XAML 属性)在
TemplatedParent 模板。
模板中设置的属性值的优先级低于模板中的触发器,并且两者的优先级都低于本地值。
您可以通过调用DependencyPropertyHelper.GetValueSource 并检查 BaseValueSource 属性来查看值是如何设置的。在模板外设置的值将具有“Local”源,而在模板内设置的值将具有“ParentTemplate”源。
将它们作为单独的源还意味着属性系统可以分别跟踪本地值和父模板值。如果您在具有模板值的属性上设置本地值,然后调用ClearValue,它将恢复为模板设置的值。
这是一个示例,它演示了覆盖模板中的值的本地值。使用下面的代码创建一个 UserControl 并将其添加到 Window。它有一个蓝色矩形,当鼠标在控件上方时会变为绿色。如果单击“设置”,代码将在矩形上设置一个本地值,该值将覆盖这两个值。如果单击“清除”,它将清除本地值并从模板中恢复值。您可以单击“显示”以查看当前值源(您需要使用键盘按下按钮才能查看 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);
}
}