WPF TemplateBinding vs RelativeSource TemplatedParent


169

Яка різниця між цими двома прив’язками:

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{TemplateBinding Property=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>

і

<ControlTemplate TargetType="{x:Type Button}">
   <Border BorderBrush="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background}">
      <ContentPresenter />
   </Border>
</ControlTemplate>

?


17
якщо вам потрібне прив'язування в два режими, вам потрібно скористатися другим варіантом
Йоахім Кершбаумер

Відповіді:


207

Прив'язка шаблонів - не зовсім одне і те ж. Документи MSDN часто пишуть люди, яким доводиться перевіряти односкладові SDE щодо функцій програмного забезпечення, тому нюанси не зовсім правильні.

Встановлення шаблонів оцінюються під час компіляції відповідно до типу, визначеного в шаблоні керування. Це дозволяє значно швидше інстанціювати складені шаблони. Просто обмацуйте ім'я в палітурці шаблонів, і ви побачите, що компілятор позначить його.

Розмітка прив'язки вирішується під час виконання. Хоча повільніше виконувати, прив'язка дозволить вирішити імена властивостей, які не видно у типі, оголошеному шаблоном. Уповільню, я зазначу, що його відносний характер, оскільки операція зв'язування займає дуже мало процесора програми. Якщо ви підірвали шаблони управління навколо з великою швидкістю, ви могли це помітити.

В якості практичної практики використовуйте прив'язку шаблонів, коли ви можете, але не боїтеся прив’язки.


18
Тож головна думка пам’ятати: Збільшити час проти виконання. Прив'язка шаблонів не працюватиме, якщо спробувати змінити його під час виконання. Правильно?
PaN1C_Showt1Me

3
Також зауважте, що використання Binding замість TemplateBinding може мати наслідки щодо того, що ви бачите під час проектування. У певних конфігураціях властивості, пов’язані за допомогою {Binding RelativeSource ...}, не з'являться у дизайнері (хоча вони все ще відображаються під час виконання), але якщо перейти на використання {TemplateBinding ...}, ці властивості оцінюються під час проектування.
lfalin

Одне, що я додам, якщо це допомагає майбутнім відвідувачам, - це те, що TemplateBinding оцінюється під час компіляції, ви не можете використовувати TemplateBinding для прив’язки до визначеного користувачем доданого властивості. Що стосується визначених користувачем властивостей, ви повинні використовувати "{Binding RelativeSource = {RelativeSource TemplatedParent} ...}"
MNB

35

Прив'язка шаблонів - Більш обмежуюча, ніж використання звичайного Прив'язування

  • Більш ефективний, ніж Біндинг, але він має меншу функціональність
  • Працює лише у візуальному дереві ControlTemplate
  • Не працює з властивостями Freezables
  • Не працює в триггері ControlTemplate
  • Забезпечує ярлик у налаштуваннях властивостей (не як багатослівний), наприклад {TemplateBinding targetProperty}

Регулярне прив’язка - не має вище обмежень TemplateBinding

  • Поважає батьківські властивості
  • Скидає цільові значення, щоб очистити будь-які явно встановлені значення
  • Приклад: <Ellipse Fill = "{Binding RelativeSource = {RelativeSource TemplatedParent}, Path = Background}" />

22

Ще одне - прив'язки шаблонів не дозволяють конвертувати значення. Вони не дозволяють вам передати конвертер і, наприклад, автоматично не перетворюють int в рядок (що є звичайним для прив'язки).


1
Дякую Мирославу, це проблема, з якою я стикався, перехід на використання TemplatedParent вирішив проблему.
MikeKulls

17

TemplateBinding - це скорочення для зв'язування з TemplatedParent, але воно не відкриває всіх можливостей класу Binding, наприклад, ви не можете керувати Binding.Mode від TemplateBinding.


1

Я думав, що TemplateBinding не підтримує типи Freezable (до яких належать об’єкти пензля). Щоб обійти проблему. Можна скористатися TemplatedParent


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.