Доступ к элементам внутри DataTemplate... Как использовать более 1 DataTemplate?

У меня есть 2 DataTemplates, определенные для элемента управления Listbox. 1 Шаблон предназначен для невыбранного состояния, а другой - для выбранного состояния (показывает больше деталей, чем невыбранное состояние).

Я последовал примеру здесь:

http://blogs.msdn.com/b/wpfsdk/archive/2007/04/16/how-do-i-programmatically-interact-with-template-generated-elements-part-ii.aspx

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

Я правильно понял, но он только находит и возвращает элемент 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 не устанавливает фокус клавиатуры.

Другие вопросы по тегам