Есть ли какая-либо семантическая разница между синтаксисом свойства элемента и синтаксисом свойства атрибута? - PullRequest
3 голосов
/ 19 июля 2010

Я думал, что синтаксис свойства элемента и синтаксис свойства атрибута не имеют большой семантической разницы.Однако я обнаружил, что между ними должно быть некоторое различие.

Например, в следующем примере просто показан простой триггер:

<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 Ответ

2 голосов
/ 19 июля 2010

Не должно быть разницы.Я думаю, что вы только что нашли ошибку в парсере XAML.

Каркас имеет специальную обработку для Setter, Trigger и Condition.Извлеките Trigger.ReceiveTypeConverter с Reflector, который отменяет обработку установщиков свойств для свойств Value и Property.Я думаю, это так, что он может анализировать свойство Value с другим типом на основе свойства Property.Например, он анализирует «красный» как кисть, а не просто строку, когда видит, что свойство является передним планом и этот передний план имеет тип кисти.

Похоже, что ловушка переопределяет все наборы свойств с именем Value или Property в Trigger, но неправильно обрабатывает синтаксис свойства элемента.Чтобы увидеть эффект, попробуйте создать расширение разметки следующим образом:

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>

Если вам действительно нужно использовать синтаксис свойства элемента, это даст вам обходной путь: создайте MarkupExtension, которое имеет свойство типа DependencyProperty с именем, отличным от «Property», и возвращает его в ProvideValue.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...