Я хочу создать пользовательский элемент управления, который может быть связан с некоторыми данными, данными извне элемента управления (требование A), а некоторые свойства XAML должны быть связаны со свойствами самого элемента управления (требование B).
Допустим, у меня есть класс данных с именем StudentData и элемент управления с именем StudentControl. Я использую этот элемент управления внутри DataGrid. Я поместил StudentControl в сетку с помощью DataGridTemplateColumn. Я как-то привязываю StudentData в текущей ячейке к элементу управления. Это требование А. Этот StudentControl хочет указать, являются ли некоторые элементы управления внутри него редактируемыми или нет. Лучший способ сделать это - выставить свойство, например StudentControl.AreSomeControlsEditable. Затем я могу привязать свойство IsEnabled этих элементов управления к этому свойству. Это требование Б.
Вот моя первая идея. Я привязываю текущий StudentData к DP StudentControl, затем внутри StudentControl меняю контекст данных на сам элемент управления:
<UserControl DataContext="{Binding RelativeSource={RelativeSource Self}}">
<TextBox
Content="{Binding Path=ExposedStudentData.Field1}" *reqA*
IsEnabled="{Binding Path=OtherProperty1}" /> *reqB*
</UserControl>
Таким образом, я полагал, что StudentControl получает StudentData извне, предоставляет те же данные StudentData и другие новые свойства (поэтому данные и другие свойства теперь находятся в одном месте, а не в двух), и затем я могу привязать их выставленные свойства в XAML (reqA + reqB выполняются одновременно). За исключением того, что это не работает из-за этой ошибки . По сути, если я установлю DataContext элемента управления на себя, он будет установлен до применения внешней привязки. Поэтому, если мой путь привязки внутри ячейки - X, а затем контекст данных изменяется, механизм привязки будет искать X в новом контексте собственных данных, а не во внешнем контексте данных сетки.
Вот моя вторая идея. Я привязываю текущий StudentData к DataContext или DP в StudentControl. Затем, чтобы получить доступ к другим открытым свойствам StudentControl, я даю имя UserControl и использую привязку ElementName:
<UserControl x:Name="self">
<TextBox
Content="{Binding Path=Field1}" *reqA*
IsEnabled="{Binding ElementName=self, Path=OtherProperty1" /> *reqB*
</UserControl>
Таким образом, я решил, что текущий контекст данных - это StudentData, и он не изменился, и я могу привязать его к этому с помощью простого пути (reqA), а я могу привязать к другим предоставляемым свойствам с помощью элемента ElementName ( reqB). Он работает в базовых сценариях, но не в DataGrid из-за этой ошибки . Я предполагаю, что проблема возникает, когда в визуальном дереве есть несколько элементов управления с одинаковыми именами.
Я действительно начинаю ненавидеть Silverlight, я начал использовать его месяц назад и уже сообщил о 9 ошибках. Всякий раз, когда я пытаюсь достичь чего-то другого, кроме простого приложения hello world или чего-то, для чего Microsoft и все остальные, кажется, используют Silverlight, я сталкиваюсь с новой ошибкой. И что теперь, как бы вы связали класс данных, заданный извне элемента управления, и некоторые другие свойства, предоставляемые элементом управления одновременно? Без, конечно, установки привязок из кода (который я делаю сейчас, но это кошмар с ListBoxes и DataTemplates) или вообще не используется привязка.