views:

29

answers:

2

Please consider the following XAML code:

<ListBox Name="listBox1" ItemsSource="{Binding}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border Name="border1">
                <TextBlock Text="{Binding}" />
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

and we assign a simple array to it:

listBox1.DataContext = new[] { "A", "B", "C" };

Now the question is how we can access the generated objects for Border (or TextBlock instances)?

  • It is not possible by "border1". It does not exist.
  • listBox1.ItemContainerGenerator.ContainerFromIndex(0) returns a ListBoxItem but content of that ListBoxItem is of type String.
  • FindName("border1") returns null

Update: What I expect to find are 3 instances of Border (and 3 TextBlocks, one in each Border).

A: 

You can access it like so:

        DataTemplate dt = this.listBox1.ItemTemplate;
        Border border = dt.LoadContent() as Border;
        // Do something with border...
Steve Ellinger
+1  A: 

Once you get the ListBoxItem, you need to walk the visual tree to find what your looking for.

Dr WPF has some great articles about it here

Here is the code from that article to search for a descendant of a particular type

  public static Visual GetDescendantByType(Visual element, Type type)
  {
      if (element.GetType() == type) return element;

      Visual foundElement = null;

      if (element is FrameworkElement)
          (element as FrameworkElement).ApplyTemplate();

      for (int i = 0;
          i < VisualTreeHelper.GetChildrenCount(element); i++)
      {
          Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
          foundElement = GetDescendantByType(visual, type);
          if (foundElement != null)
              break;
      }

      return foundElement;
  }
mdm20
However, I just wanted to point out Dr. WPF also states that manipulating the visual tree in this manner should rarely be needed. There are much more 'correct' (reliable and/or resilient) ways of doing just about anything.
Alex Paven
Unfortunately this cannot be the answer: What I am looking for are "instances" or Border when they are generated not the one that is inside ItemTemplate. Here I expect to find "3" objects of type Border (I have 3 items in DataContext)
shayan
@shayan: Walking the visual tree will get you the instance data you want. Just use the listview as the Visual and Border as the type. But like Alex suggested, their generally is a better approach. What are you trying to do with the Border when you get it?
mdm20
This question was actually raised as a solution to the situation that is explained here: http://stackoverflow.com/questions/3802102/animating-this-and-other-in-wpf
shayan