Доступ к элементам внутри DataTemplate... Как использовать более 1 DataTemplate?
У меня есть 2 DataTemplates, определенные для элемента управления Listbox. 1 Шаблон предназначен для невыбранного состояния, а другой - для выбранного состояния (показывает больше деталей, чем невыбранное состояние).
Я последовал примеру здесь:
о том, как получить доступ к элементам внутри шаблонов данных из кода.
Я правильно понял, но он только находит и возвращает элемент UnSelected DataTemplate. Но когда я ищу элемент в Selected DataTemplate, я получаю исключение NullReferenceException.
Что я могу делать не так?
2 ответа
Что ты делаешь не так?
Я бы сказал, что вы делаете неправильно, пытаясь получить доступ к элементам внутри DataTemplate из-за кода. Капризный капризный!
Не говоря уже о шутках, в 99,9% случаев я вижу, как кто-то пытается получить доступ к элементу внутри DataTemplate из кода, потому что его приложение плохо спроектировано, без (или нескольких) привязок и вообще без модели представления. Многие новички склонны хранить свои данные непосредственно в элементах пользовательского интерфейса, а не использовать модель представления. Я думаю, что это потому, что их умы были испорчены опытом VB, WinForms и ASP.NET, где это был "нормальный" способ сделать это. Существует тысяча причин использовать модель представления и связывать ваши данные, а не хранить их в элементах пользовательского интерфейса. Посмотрите "модель вид модели" онлайн для более подробной информации.
Теперь, чтобы ответить на ваш вопрос:
Любой данный ListBoxItem может иметь только один DataTemplate одновременно. Это связано с тем, что его ContentPresenter имеет только одно свойство ContentTemplate, и это свойство не может иметь два разных значения.
Из-за этого визуальное дерево в ListBoxItem всегда будет генерироваться из одного определенного шаблона, а не из комбинации нескольких шаблонов. Если вы измените ItemTemplate объекта ListBox или иным образом обновите ListBoxItem.ContentTemplate, визуальное дерево, созданное старым шаблоном, будет отброшено и построено новое.
Позвольте мне повторить еще раз: если вы измените шаблоны данных, визуальное дерево, созданное старым шаблоном данных, будет отброшено и построено новое визуальное дерево.
Вы можете иметь сотню шаблонов данных, определенных и пригодных для использования с данным ListBoxItem, но только для одного из них одновременно может быть создано визуальное дерево. И это единственные элементы, которые на самом деле существуют как часть визуального дерева. Все остальные шаблоны существуют только как шаблоны - для них не создано никаких реальных элементов.
Другими словами: бессмысленно задавать вопросы о том, как найти элементы в двух разных визуальных деревьях, созданных двумя разными шаблонами в одном и том же элементе управления, потому что один элемент управления не может иметь два разных активных шаблона одновременно.
Надеюсь, это прояснит для вас.
Последний совет: прочитайте статью о MVVM и прекратите попытки доступа к элементам внутри DataTemplates ASAP. Однако, если вы считаете, что у вас могут быть те 0,1%, у которых действительно есть веские причины для доступа к элементам внутри шаблонов, напишите свою реальную причину желания сделать это и, возможно, я смогу дать дальнейшие рекомендации.
Настройка фокуса клавиатуры может быть одной из причин, по которой вам нужен доступ к элементам таблицы данных. MVVM не решит эту проблему, и FocusManager не устанавливает фокус клавиатуры.