Вопрос

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top