views:

570

answers:

3

I'm creating a custom control called FooControl derived from ItemsControl have a default style defined for the same in themes\generic.xaml.

The default style for FooControl sets ItemsPanel property to another custom panel called FooPanel as below (I don't think the usage of custom panel matters for this question).

<Setter Property="ItemsPanel">
  <Setter.Value>
    <ItemsPanelTemplate>
      <local:FooPanel IsItemsHost="True"/>
    </ItemsPanelTemplate>
  </Setter.Value>
</Setter>

In the code behind of my FooControl, I want to get access to the instance of FooPanel that was created automatically. By looking in reflector I found that ItemsControl does have a property called ItemsHost but I cannot access it from FooControl as ItemsHost is internal

Can someone plz suggest me a reliable way to get reference to the instance of FooPanel?

A: 

You can use VisualTreeHelper.GetChild(...). I believe it should be the first or second child of your ItemsControl subclass.

Jeremiah Morrill
A: 

Unfortunately the ItemsControl control does not expose a reference to this element (in fact, I have a feeling that the ItemsControl doesn't even have access to it itself).

Using VisualTreeHelper.GetChild() as suggested in the previous post may work, but it will break if the items control is restyled in such a way that causes the items panel do be nested further down.

A slightly less fragile (but still far from perfect) way to get a reference is to get the parent of the container for the first child (assuming that your items control contains at least one item)

Panel itemsPanel;

if (Items.Count == 0)
{
   itemsPanel = null;
}
else
{
   var firstContainer = ItemContainerGenerator.ContainerFromIndex(0);

   itemsPanel = VisualTreeHelper.GetParent(firstContainer) as Panel;
}

Note: This only works in SL3 and above since it uses the ItemContainerGenerator property (I believe a work around may exist for SL2)

Stephen Feest
A: 

I am directing this at Stephen Feest, because I cannot comment on answers. I have tried using your suggestion of ItemContainerGenerator.ContainerFromIndex(0), but it always returns null. I have items in my collection and I have placed the code in the ItemsChanged event. I have even tried instead of using an index of 0, using Items.Count-1, but it always returns null. Is there a specific event or place that I should place this code so that it does not return null?

Hydroslide

related questions