DataTemplate
<DataTemplate x:Key="postBody" TargetType="{x:Type Post}"> <Grid> <TextBlock Text="{Binding Path=author}"/> <Button Click="btnDelete_Click" Content="Delete"/> </Grid> </DataTemplate> <ListBox ItemTemplate="{StaticResource postBody}" ItemSource="{Binding Posts}"/>
Code behind to get a reference to object owning btnDelete:
private void btnDelete_Click(object sender, RoutedEventArgs e) { var post = ((Button)sender).DataContext as Post; if (post == null) { throw new InvalidOperationException("Invalid DataContext"); } Console.WriteLine(post.author); }
How to: Find DataTemplate-Generated Elements
To find elements generated by a DataTemplate:
<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>
We have to find the ContentPresenter first:
// 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; }
Example 1
For a ListBoxItem:
<ListBox Name="listBox"> <ListBox.ItemTemplate> <DataTemplate DataType="x:Type local:NumericIconDefinition"> <Grid> <ComboBox Name="IconComboBox"/> </Grid> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
ListBoxItem lbi = (ListBoxItem)listBox.ItemContainerGenerator.ContainerFromIndex(IndexInListBox); ComboBox cb = (ComboBox)listBox.ItemTemplate.FindName("IconComboBox", lbi);
Example 2
For a ListBoxItem:
<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"/>
// 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));
Source: ZAG Log: How to get a ListBoxItem from a data bound ListBox