Работает ли привязка только с DependencyProperty?

MSDN говорит,

  • Каждая привязка обычно имеет эти четыре компонента: цель привязки объект, свойство target, привязка источник и путь к значению в источник связывания для использования. Например, если вы хотите связать содержимое TextBox для свойства Name Объект Employee, ваш целевой объект TextBox, целевое свойство свойство Text, используемое значение Имя, а исходным объектом является Объект сотрудника.

  • Свойство target должно быть зависимым.

Вышеприведенная выдержка объясняет, почему работает следующий код,

<TextBox Text="{Binding EmployeeName}">

Это работает, потому что Text является свойством зависимости. До этого момента все в порядке!


Мой вопрос:

Свойство IF target должно быть свойством зависимости для привязки для работы, то как работает следующий Setter? Обратите внимание, что Значение в Setter НЕ является свойством зависимостей!

<Style TargetType="{x:Type TextBox}">
      <Setter Property="Text" Value="{Binding EmployeeName}"/>
</Style>

У меня есть объяснение. Но я не уверен, что это правильно. Позвольте мне сначала объяснить это, а затем, вы, ребята, меня исправите, если я ошибаюсь.: -)

Я думаю, поскольку тип значения Объект, это означает, что он может содержать экземпляры любого типа. Он может содержать экземпляр типа "Тип привязки". Он, однако, не может участвовать в процессе оценки (или разрешения) выражения Binding, поскольку он не является свойством зависимостей.. Объект Style просто переносит этот объект привязки (значение которого имеет значение) из Setter в TextBox как таковой, не оценивая/не изменяя значение привязки. Таким образом, приведенный выше Сеттер становится эквивалентным этому:

 Text="{Binding EmployeeName}"

И поскольку теперь Text является свойством зависимости, он может разрешить значение привязки. Итак, сначала появляется, что целью привязки является значение, но на самом деле текст является целью привязки.

Это похоже, что Setter является почтальоном, Value сама по себе является почтовым пакетом, экземпляр Binding (то есть то, что имеет значение) - это письмо. Почтальон (т.е. Сеттер) доставляет письмо (например, экземпляр привязки) объекту Target (т.е. свойство Text), не открывая его, то есть не зная, какое сообщение (например, EmployeeName) несет письмо.

Пожалуйста, поправьте меня, если я ошибаюсь.

Ответ 1

XAML устанавливает Setter.Value объекту типа Binding. Созданный таким образом Style устанавливает свойство зависимостей Text на целевом объекте с этим Binding, поэтому привязка будет обновлять Text всякий раз, когда изменяется исходное свойство.

Если Setter.Value было свойством зависимостей, тогда установщик окажется промежуточным звеном в уведомлении об изменении свойства: изменяется исходное свойство, связывание уведомляет установщика, сеттер уведомляет цель. Поскольку это просто свойство CLR, установщик фактически не участвует в уведомлении об изменении: изменяется исходное свойство, а привязка уведомляет цель.

Ответ 2

Это правильно. Если вы посмотрите на исходный код элементов управления WPF toolkit, вы увидите, как это делается. DataGrid делает это в довольно многих местах (например, конкретные столбцы, передающие привязку содержимого к ячейке). Я попытаюсь вспомнить, чтобы добавить ссылку на конкретный файл и строку, где она была сделана после работы.

Edit Хорошим примером является свойство Binding в классе DataGridBoundColumn. Вы можете видеть, что он используется в

internal void ApplyBinding(DependencyObject target, DependencyProperty property)

Если вам интересны расширенные шаблоны для управления WPF и Silverlight, я настоятельно рекомендую просмотреть их соответствующие инструменты. Они хорошо комментируются вообще, и некоторые элементы управления используют какой-то классный код.