Как работает привязка имени элемента?

Я помню, как пару недель назад читал, что он иногда не работает внутри шаблонов, и я недавно пытался связать вещи в двух разных окнах, и он не мог найти объявления имен, поэтому я предположил, что он был локальным пространство имен класса и просто связанное, вместо этого устанавливая datacontext. Тем не менее, мне очень интересно, когда я могу использовать имя привязки и когда не могу, потому что это гораздо удобнее, когда это возможно.

edit: прочитав эту статью, я нашел это интересным:

"По этой причине стили и шаблоны определяют свои собственные XAML-имена, независимо от любого места в дереве объектов, где применяется стиль или шаблон."

Если это правда, не означает ли это, что Binding ElementName вообще не должно работать в шаблонах? Но тогда у меня есть определенные рабочие привязки к ElementName в моих шаблонах. Это самая запутанная часть, почему некоторые привязки случайно работают внутри шаблонов, а другие нет? У него должен быть какой-то метод для попыток разрешить имя, даже если оно не находится в шаблоне или том же namescope

1 ответ

В принципе, вам нужно быть в той же области имен (читайте это). Большинство элементов пользовательского интерфейса находятся в одном и том же дереве, использующем одну и ту же область имен, однако могут быть разрывы и барьеры (стили/шаблоны), и если у вас есть абстрактные объекты, такие как столбцы DataGrid, они вообще не имеют области имен.

Я работал с WPF достаточно долго, чтобы угадать, когда у меня возникнут проблемы, и я знаю общие области, но не думаю, что там есть простой способ рассказать во всех ситуациях.

Если это правда, не означает ли это, что Binding ElementName вообще не должно работать в шаблонах? Но тогда у меня определенно есть рабочие привязки к ElementName в моих шаблонах.

Внутри просто отлично, это та же область. Дело здесь в том, что если вы примените шаблон, и у них не будет собственных областей, возникнут конфликты.

например.

<button>
<p>Если развернуть <code>ControlTemplate</code>, вы получите что-то вроде:</p>
<pre class="prettyprint linenums"><border name="bd" background="{TemplateBinding Background}">...</border>
<border name="bd" background="{TemplateBinding Background}">...</border>

Очевидно, что мы получим конфликт имен.

То же самое для DataTemplates в ItemsControls, если вы укажете элементы управления в шаблоне, имя которого будет конфликтовать с тем же экземпляром элемента управления в применяемом шаблоне других элементов.

В другой заметке вы можете привязываться изнутри шаблона к внешней стороне, поскольку логически может быть только один экземпляр с этим именем или вы можете дать им отличный приоритет в зависимости от того, как "закрыть" область имени, например

<textbox name="tb" text="Test">
<itemscontrol itemssource="ABC">
 <itemscontrol.itemtemplate>
 <datatemplate>
 <textblock text="{Binding Text, ElementName=tb}">
 </textblock></datatemplate>
 </itemscontrol.itemtemplate>
</itemscontrol>
</textbox>

licensed under cc by-sa 3.0 with attribution.