2010-07-18 39 views
3

我认为元素属性语法和属性属性语法没有太大的语义差异。但是,我发现一定有一些区别。元素属性语法和atrribute属性语法之间是否存在语义上的区别?

E.g.下面的例子只是演示了一个简单的触发器:

<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,它抛出一个异常说二传手! (不触发)需要属性和值。

<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> 

那么,什么元素属性语法和属性属性语法之间的隐藏区别?

回答

2

应该没有区别。我想你只是在XAML分析器中发现了一个错误。

该框架对Setter,Trigger和Condition有特殊处理。使用Reflector检出Trigger.ReceiveTypeConverter,这会覆盖Value和Property属性的属性设置器的处理。我认为这样可以使用基于Property属性的不同类型解析Value属性。例如,当它看到“属性是前景”并且前景属于“画笔”类型时,它会将“红色”解析为画笔而不是字符串。

它看起来像钩子覆盖Trigger中名为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> 

然而,这会工作,因为属性未命名为“物业”:

<Trigger.Property> 
    <local:Test> 
     <local:Test.Property2>IsMouseOver</local:Test.Property2> 
    </local:Test> 
</Trigger.Property> 

,这将正常工作,因为它使用属性语法:

<Trigger.Property> 
    <local:Test Property="IsMouseOver"/> 
</Trigger.Property> 

如果你真的需要使用元素属性的语法,这会给你一个解决方法:创建具有比“财产”,其他类型的DependencyProperty命名的东西属性一个的MarkupExtension,并返回在ProvideValue。