2010-07-18 91 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。