我认为元素属性语法和属性属性语法在语义上没有太大区别。但是,我发现肯定有一些不同。
例如下面的例子只是演示了一个简单的触发器:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button><Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock x:Name="hello" Text="Hello" />
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Red" TargetName="hello"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template></Button>
</Page>
但是,如果我对触发器的属性 Property
使用元素属性语法,它会抛出一个异常,指出该 setter ! (不是触发器)需要属性和值。
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button><Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<TextBlock x:Name="hello" Text="Hello" />
<ControlTemplate.Triggers>
<Trigger Value="True">
<Trigger.Property>IsMouseOver</Trigger.Property>
<Setter Property="Foreground" Value="Red" TargetName="hello"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template></Button>
</Page>
那么,元素属性语法和属性属性语法之间隐藏的区别是什么?
最佳答案
应该没有区别。我认为您刚刚在 XAML 解析器中发现了一个错误。
框架对 Setter、Trigger 和 Condition 有特殊处理。查看Trigger.ReceiveTypeConverter使用 Reflector,它会覆盖 Value 和 Property 属性的属性 setter 的处理。我认为这是为了它可以根据 Property 属性解析具有不同类型的 Value 属性。例如,当它看到 Property 是 Foreground 并且 Foreground 是 Brush 类型时,它会将“Red”解析为 Brush 而不仅仅是 String。
看起来该 Hook 覆盖了触发器中所有名为 Value 或 Property 的属性集,但它没有正确处理元素属性语法。要查看效果,请尝试创建如下标记扩展:
public class Test
: MarkupExtension
{
public DependencyProperty Property { get; set; }
public DependencyProperty Property2 { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
return Property ?? Property2;
}
}
以下 XAML 将出现与第二个示例相同的错误,您可以通过设置断点来验证属性从未设置:
<Trigger.Property>
<local:Test>
<local:Test.Property>IsMouseOver</local:Test.Property>
</local:Test>
</Trigger.Property>
但是,这会起作用,因为该属性未命名为“Property”:
<Trigger.Property>
<local:Test>
<local:Test.Property2>IsMouseOver</local:Test.Property2>
</local:Test>
</Trigger.Property>
这会起作用,因为它使用属性语法:
<Trigger.Property>
<local:Test Property="IsMouseOver"/>
</Trigger.Property>
如果您确实需要使用元素属性语法,这将为您提供一个解决方法:创建一个 MarkupExtension,它具有 DependencyProperty 类型的属性,名称不是“Property”,然后在 ProvideValue 中返回它。
关于c# - 元素属性语法和属性属性语法在语义上有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3277375/