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
?
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 thatif
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: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.