代码之家  ›  专栏  ›  技术社区  ›  TN.

元素属性语法和属性属性语法在语义上有什么区别吗?

  •  3
  • TN.  · 技术社区  · 15 年前

    我认为元素属性语法和属性属性语法在语义上没有很大的区别。然而,我发现一定有一些不同。

    例如,下面的示例只是演示了一个简单的触发器:

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

    那么,问题是什么 元素属性语法和属性属性语法的区别?

    1 回复  |  直到 15 年前
        1
  •  2
  •   Quartermeister    15 年前

    不应该有什么区别。我想你刚刚在XAML解析器中发现了一个bug。

    框架对Setter、Trigger和Condition有特殊的处理。退房 Trigger.ReceiveTypeConverter 使用Reflector,它重写对值和属性的属性设置器的处理。我认为这是因为它可以基于属性用不同的类型解析Value属性。例如,当它看到属性是Foreground并且前景是Brush类型时,它将“Red”解析为一个笔刷,而不仅仅是一个字符串。

    看起来钩子覆盖了触发器中名为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>
    

    推荐文章