Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
swdev:dotnet:wpf:datatemplates [2012/11/14 13:00]
smayr created
swdev:dotnet:wpf:datatemplates [2012/12/07 17:15] (current)
smayr [Example 2]
Line 24: Line 24:
 } }
 </code> </code>
 +
 +== How to: Find DataTemplate-Generated Elements ==
 +
 +To find elements generated by a DataTemplate:
 +<code xml>
 +<DataTemplate x:Key="myDataTemplate">
 +  <TextBlock Name="textBlock" FontSize="14" Foreground="Blue">
 +    <TextBlock.Text>
 +      <Binding XPath="Title"/>
 +    </TextBlock.Text>
 +  </TextBlock>
 +</DataTemplate>
 +...
 +<ListBox Name="myListBox" ItemTemplate="{StaticResource myDataTemplate}"
 +         IsSynchronizedWithCurrentItem="True">
 +  <ListBox.ItemsSource>
 +    <Binding Source="{StaticResource InventoryData}" XPath="Books/Book"/>
 +  </ListBox.ItemsSource>
 +</ListBox>
 +</code>
 +We have to find the ContentPresenter first:
 +<code csharp>
 +// Getting the currently selected ListBoxItem 
 +// Note that the ListBox must have 
 +// IsSynchronizedWithCurrentItem set to True for this to work
 +ListBoxItem myListBoxItem =
 +    (ListBoxItem)(myListBox.ItemContainerGenerator.ContainerFromItem(myListBox.Items.CurrentItem));
 +
 +// Getting the ContentPresenter of myListBoxItem
 +ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
 +
 +// Finding textBlock from the DataTemplate that is set on that ContentPresenter
 +DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
 +TextBlock myTextBlock = (TextBlock)myDataTemplate.FindName("textBlock", myContentPresenter);
 +
 +// Do something to the DataTemplate-generated TextBlock
 +MessageBox.Show("The text of the TextBlock of the selected list item: "
 +    + myTextBlock.Text);
 +. . .
 +private childItem FindVisualChild<childItem>(DependencyObject obj)
 +    where childItem : DependencyObject
 +{
 +    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
 +    {
 +        DependencyObject child = VisualTreeHelper.GetChild(obj, i);
 +        if (child != null && child is childItem)
 +            return (childItem)child;
 +        else
 +        {
 +            childItem childOfChild = FindVisualChild<childItem>(child);
 +            if (childOfChild != null)
 +                return childOfChild;
 +        }
 +    }
 +    return null;
 +}
 +</code>
 +Source: [[http://msdn.microsoft.com/en-us/library/system.windows.frameworktemplate.findname.aspx|MSDN: FrameworkTemplate.FindName Method]]   
 +
 +=== Example 1 ===
 +For a ListBoxItem:
 +<code xml>
 +<ListBox Name="listBox">
 +    <ListBox.ItemTemplate>
 +        <DataTemplate DataType="x:Type local:NumericIconDefinition">
 +           <Grid>
 +                <ComboBox Name="IconComboBox"/>
 +           </Grid>
 +        </DataTemplate>
 +    </ListBox.ItemTemplate>
 +</ListBox>
 +</code>
 +<code csharp>
 +ListBoxItem lbi = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromIndex(IndexInListBox);
 +ComboBox cb = (ComboBox)listBox.ItemTemplate.FindName("IconComboBox", lbi);
 +</code>  
 +
 +=== Example 2 ===
 +For a ListBoxItem:
 +<code xml>
 +<Window.Resources>
 +    <local:GreekGods x:Key="greekGods"/>
 +    <DataTemplate x:Key="itemTemplate">
 +        <TextBlock Text="{Binding Path=Name}" />
 +    </DataTemplate>
 +</Window.Resources>
 +. . .    
 +<ListBox ItemsSource="{StaticResource greekGods}" ItemTemplate="{StaticResource itemTemplate}" Name="listBox"/>
 +</code>
 +
 +<code csharp>
 +// To get GreekGod object
 +GreekGod greekGod = (GreekGod)(listBox.Items[0]);
 +
 +// To get ListBoxItem container holding object GreekGod
 +ListBoxItem lbi1 = (ListBoxItem)(listBox.ItemContainerGenerator.ContainerFromIndex(0));
 +ListBoxItem lbi2 = (ListBoxItem)(listBox.ItemContainerGenerator.ContainerFromItem(listBox.Items.CurrentItem));
 +</code>  
 +
 +Source: [[http://www.zagstudio.com/blog/7#.UMESToM72dI|ZAG Log: How to get a ListBoxItem from a data bound ListBox]]