Windows Phone, ItemsControl.ContainerFromIndex returns null

173 views Asked by At

I've got a templated control. Part of the template looks like the following:

<ItemsControl x:Name="icSubObjects">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Horizontal" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <local:StateButton Content="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

ItemsSource for this panel is being set from code behind.

Then in code I'm trying to access the actual objects generated from data:

for (int i = 0; i < icSubObjects.Items.Count; i++)
{
    var element = icSubObjects.ContainerFromIndex(i);
    if (element is StateButton)
    {
        var btn = element as StateButton;

        // btn is always null, despite icSubObjects.Items.Count being > 0
    }                    
}

After caling icSubObjects.ContainerFromIndex(i), I always get null, despite fact, that objects are correctly displayed and icSubObjects.Items.Count is greater than 0. What can I do to make this method work correctly? (or what am I doing wrong?)


Edit: The plot unfolds

I found on the Internet a trick, which fixes the problem. The trick is to "touch" Children property of one of containers, which holds the ItemsControl control:

var temp = gContainer.Children;

The containers are then populated correctly.

I've got another problem though. From ContainerFromIndex I get the ContentPresenter. How can I access StateButton, which is inside DataTemplate of that ContentPresenter?

1

There are 1 answers

0
yasen On

From reading the comments below the question, I understand that you already know why btn is always null (although, I guess it's not even entering that if statement). Anyway, I'll say it again for anyone who wants to know.

ContainerFromIndex returns a ContentPresenter (in most cases). Not a StateButton.

Now, to get the StateButton that you want from the ContentPresenter, I think you can do this:

var btn = (StateButton)VisualTreeHelper.GetChild(contentPresenter, 0);

If that doesn't work (that is, the StateButton isn't the only and first child of the ContentPresenter), just check the visual tree and modify the code to get the element that you need from the tree.