Find control inside Listbox.ItemTemplate (WPF C#)

c#, listbox, mouseevent, selecteditem, wpf

Solution

ListBoxItem myListBoxItem = (ListBoxItem)(lstUniqueIds.ItemContainerGenerator.ContainerFromIndex(lstUniqueIds.SelectedIndex));
ContentPresenter myContentPresenter = FindVisualChild<ContentPresenter>(myListBoxItem);
DataTemplate myDataTemplate = myContentPresenter.ContentTemplate;
CheckBox target = (CheckBox)myDataTemplate.FindName("chkUniqueId", myContentPresenter);
if (target.IsChecked)
{
    target.IsChecked = false;
}
else
{
    target.IsChecked = true;
}

Function `FindVisualChild` can be found on the MSDN page FrameworkTemplate.FindName Method:

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;
}

Problem

I have some problems finding the right `TextBlock` control inside a `StackPanel`. My markup: ``` <ListBox Name="lstTimeline" ItemContainerStyle="{StaticResource TwItemStyle}" MouseDoubleClick="lstTimeline_MouseDoubleClick"> <ListBox.ItemTemplate> <DataTemplate> <DockPanel MaxWidth="{Binding ElementName=lstTimeline, Path=ActualWidth}"> <Border Margin="10" DockPanel.Dock="Left" BorderBrush="White" BorderThickness="1" Height="48" Width="48" HorizontalAlignment="Center"> <Image Source="{Binding ThumbNail, IsAsync=True}" Height="48" Width="48" /> </Border> <StackPanel Name="stkPanel" Margin="10" DockPanel.Dock="Right"> <TextBlock Text="{Binding UserName}" FontWeight="Bold" FontSize="18" /> <TextBlock Text="{Binding Text}" Margin="0,4,0,0" FontSize="14" Foreground="#c6de96" TextWrapping="WrapWithOverflow" /> <TextBlock Text="{Binding ApproximateTime}" FontSize="14" FontFamily="Georgia" FontStyle="Italic" Foreground="#BBB" /> <TextBlock Text="{Binding ScreenName}" Name="lblScreenName" FontSize="14" FontFamily="Georgia" FontStyle="Italic" Foreground="#BBB" Loaded="lblScreenName_Loaded" /> </StackPanel> </DockPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> ``` My double click code: ``` private void lstTimeline_MouseDoubleClick(object sender, MouseButtonEventArgs e) { ListBoxItem lbi = (lstTimeline.SelectedItem as ListBoxItem); StackPanel item = lbi.FindName("stkPanel") as StackPanel; if (item != null) MessageBox.Show("StackPanel null"); TextBlock textBox = item.FindName("lblScreenName") as TextBlock; if (textBox != null) MessageBox.Show("TextBlock null"); MessageBox.Show(textBox.Text); } ``` But the `StackPanel` is null. How do find the right `TextBlock` in `SelectedItem`? Thanks for your help.

Original source