views:

164

answers:

1

I have seen solutions to a very similar issue, yet it doesn't translate to mine. (Namely, this article: http://blogs.msdn.com/wpfsdk/archive/2007/04/16/how-do-i-programmatically-interact-with-template-generated-elements-part-ii.aspx)

My ItemsControl is bound to an observable collection, which can have items dynamically added to it.

When I add an item to the observable collection, the templated item renders properly in my itemscontrol, but I can't figure out how to access it. My my observable colleciton changed code, I am trying to access information about. I am using a custom DataTemplateSelector to return one of 3 different dataTemplates, based on the item's data in the collection.

Here is an outline of my 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>

The solutions I've seen suggest using ItemContainerGenerator.ContainerFromItem(xxx)

In this examples, they are always looking for information about a ListBox or ComboBox (which inherit from ContentControl). However, when I call (in my code-behind) myItemsControl.ItemContainerGenerator.ContainerFromItem(xxx), I receive a ContentPresenter, rather than the ContentControl I expect.

Then, when I try to access the ContentTemplate of this ContentPresenter, I get a null object exception.

I have a hunch that the rest of my troubles descend from there.

All I want to do is find a textbox from the datatemplate in my newly created control, and give it focus.

Help! :-)

+2  A: 

You need to get a handle to the DataTemplate itself, and use its FindName method, referencing the parent control of your item.

For example:

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

So this finds a control called "textBox1" inside the item.

If you're not using a named DataTemplate (ie one with x:Key="MyItemTemplate") and instead using DataType="..." to define a DataTemplate to be used for specific types, the method by which you find the template changes slightly:

var actionKey = new DataTemplateKey(typeof(MyCustomClass));
var actionTemplate = Resources[actionKey] as DataTemplate;
Matt Hamilton
Thanks for your quick help.I am using a named template, as in your first example. (Forgot to mention i'm using visual basic, btw)Dim myCp As ContentPresenter = SP_ItemsControl.ItemContainerGenerator.ContainerFromItem(_ObsCol.ElementAt(newIndex))Dim template As DataTemplate = Me.FindResource("RNQuestionTemplate")Dim ctl As BindableRTB = template.FindName("myRTB", myCp)ctl.Focus()I am getting the following error on the next-to-last line:"This operation is valid only on elements that have this template applied."But, this is an item with that template applied!?! :-)
Matt H.
wow, sorry... no line breaks there.
Matt H.
A-HA! It's working now. Thanks again for your help. My problem at the end there is that I was trying to get the DataTemplate before it was actually set on the item. I don't know why this is happening, but I've just had to work around the timing of that.
Matt H.
@Matt Always good to help out a fellow "Matt H"! ;-)
Matt Hamilton