【问题标题】:Is there any semantical difference between element property syntax and atrribute property syntax?元素属性语法和属性属性语法之间是否存在语义差异?
【发布时间】:2011-03-17 16:23:40
【问题描述】:

我认为元素属性语法和属性属性语法没有太大的语义差异。但是,我发现肯定有一些不同。

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

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

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

【问题讨论】:

    标签: c# .net wpf xaml exception


    【解决方案1】:

    应该没有区别。我认为您刚刚在 XAML 解析器中发现了一个错误。

    框架对 Setter、Trigger 和 Condition 进行了特殊处理。使用 Reflector 查看 Trigger.ReceiveTypeConverter,它覆盖了对 Value 和 Property 属性的属性设置器的处理。我认为这是为了它可以根据 Property 属性解析具有不同类型的 Value 属性。例如,当它看到 Property is Foreground 并且 Foreground 是 Brush 类型时,它会将“Red”解析为 Brush 而不仅仅是 String。

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

    如果您确实需要使用元素属性语法,这将为您提供一种解决方法:创建一个具有类型 DependencyProperty 的属性的 MarkupExtension,名称不是“Property”,然后在 ProvideValue 中返回它。

    【讨论】:

      猜你喜欢
      • 2016-08-20
      • 2011-09-03
      • 2023-03-28
      • 1970-01-01
      • 2014-05-17
      • 1970-01-01
      • 2021-03-05
      • 2016-01-02
      • 2019-02-22
      相关资源
      最近更新 更多