Как я могу получить DataTemplate (и конкретные объекты) элемента в ItemsControl? - PullRequest
4 голосов
/ 16 февраля 2010

Я видел решения очень похожей проблемы, но она не переводит на мою. (А именно эта статья: http://blogs.msdn.com/wpfsdk/archive/2007/04/16/how-do-i-programmatically-interact-with-template-generated-elements-part-ii.aspx)

Мой ItemsControl привязан к наблюдаемой коллекции, в которую можно динамически добавлять элементы.

Когда я добавляю элемент в наблюдаемую коллекцию, шаблонный элемент правильно отображается в моем элементе управления, но я не могу понять, как получить к нему доступ. Мой наблюдаемый сборник изменил код, о котором я пытаюсь получить доступ. Я использую пользовательский DataTemplateSelector для возврата одного из 3 различных dataTemplates, основанных на данных элемента в коллекции.

Вот схема моего ItemsControl XAML:

<ItemsControl Name="myItemsControl" ItemTemplateSelector="{StaticResource myTempSelector}">
    <ItemsControl.Template>
        <ControlTemplate TargetType="ItemsControl">
            <ItemsPresenter/>
        </ControlTemplate>
    </ItemsControl.Template>
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel></StackPanel>   
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    </ItemsControl>

Решения, которые я видел, предлагают использовать ItemContainerGenerator.ContainerFromItem(xxx)

В этих примерах они всегда ищут информацию о ListBox или ComboBox (которые наследуются от ContentControl). Однако когда я вызываю (в моем коде) myItemsControl.ItemContainerGenerator.ContainerFromItem(xxx), я получаю ContentPresenter, а не ожидаемый ContentControl.

Затем, когда я пытаюсь получить доступ к ContentTemplate этого ContentPresenter, я получаю исключение нулевого объекта.

У меня есть предчувствие, что остальные мои проблемы происходят оттуда.

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

Помощь! : -)

1 Ответ

5 голосов
/ 16 февраля 2010

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

Например:

var item = myItemsControl.ItemContainerGenerator.ContainerFromItem(xxx);
var template = this.Resources["MyItemTemplate"] as DataTemplate;
var ctl = template.FindName("textBox1", item) as FrameworkElement;

Таким образом, это находит элемент управления с именем "textBox1" внутри элемента.

Если вы не используете именованный DataTemplate (то есть с x: Key = "MyItemTemplate") и вместо этого используете DataType = "...", чтобы определить DataTemplate, который будет использоваться для определенных типов, метод, которым найти шаблон слегка меняется:

var actionKey = new DataTemplateKey(typeof(MyCustomClass));
var actionTemplate = Resources[actionKey] as DataTemplate;
...