WPF ListBox - получение UIElement вместо SelectedItem
Я создал ListBox
с DataTemplate
как Itemtemplate
. Однако есть ли простой способ получить доступ к сгенерированному UIElement
вместо SelectedItem
в codebehind?
Когда я получаю доступ к SelectedItem
, я просто получаю выбранный объект из своего
ItemsSource
коллекция. Есть ли способ доступа к UIElement
(т.е.
элемент, сгенерированный из DataTemplate
вместе со связанным объектом)?
Ответы
Ответ 1
Вы ищете свойство ItemContainerGenerator. Каждый ItemsSource
имеет экземпляр ItemContainerGenerator. Этот класс имеет следующий метод, который может вас заинтересовать: ContainerFromItem (экземпляр объекта).
Когда у вас есть дескриптор ListBoxItem
, вы можете перейти к просмотру логического и визуального дерева. Проверьте помощник по логическому дереву и помощник по визуальному дереву.
Как сказал Энди в комментариях, тот факт, что элемент существует в вашей коллекции, не означает, что для него создан контейнер. Любой вид сценария виртуализации панели поднимет эту проблему; Элементы UIE будут повторно использоваться в различных элементах. Будьте осторожны с этим.
Ответ 2
siz, Энди и Бодейкер абсолютно правы.
Вот как я смог получить текстовое поле выбранного элемента списка с помощью его дескриптора.
var container = listboxSaveList.ItemContainerGenerator.ContainerFromItem(listboxSaveList.SelectedItem) as FrameworkElement;
if (container != null)
{
ContentPresenter queueListBoxItemCP = VisualTreeWalker.FindVisualChild<ContentPresenter>(container);
if (queueListBoxItemCP == null)
return;
DataTemplate dataTemplate = queueListBoxItemCP.ContentTemplate;
TextBox tbxTitle = (TextBox)dataTemplate.FindName("tbxTitle", queueListBoxItemCP);
tbxTitle.Focus();
}
(Примечание: здесь VisualTreeWalker является моей собственной оболочкой над VisualTreeHelper с различными полезными функциями)