WPF ListBox - Получение UIElement вместо SelectedItem - PullRequest
12 голосов
/ 04 марта 2009

Я создал ListBox с DataTemplate как Itemtemplate. Однако существует ли простой способ доступа к сгенерированному UIElement вместо SelectedItem в коде позади?

Когда я получаю доступ к SelectedItem, я просто получаю выбранный объект из моего ItemsSource коллекция. Есть ли способ получить доступ к UIElement (т.е. элемент, сгенерированный из DataTemplate вместе со связанным объектом)?

Ответы [ 2 ]

13 голосов
/ 04 марта 2009

Вы ищете свойство ItemContainerGenerator . Каждый ItemsSource имеет экземпляр ItemContainerGenerator . Этот класс имеет следующий метод, который может вас заинтересовать: ContainerFromItem (экземпляр объекта) .

Получив дескриптор ListBoxItem, вы можете перейти к логическому и визуальному дереву. Посмотрите Помощник по логическому дереву и Помощник по визуальному дереву .

Как сказал Энди в комментариях, тот факт, что элемент существует в вашей коллекции, не означает, что для него создан контейнер. Любой вид сценария виртуализации панели поднимет эту проблему; Элементы UIE будут повторно использоваться в различных элементах. Будьте осторожны и с этим.

4 голосов
/ 02 августа 2013

siz , Andy и Bodeaker абсолютно правы.

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

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 с различными полезными функциями)

...