2009-11-25 19 views
6

Tengo algunos problemas para encontrar el control TextBlock correcto dentro de un StackPanel. Mi marcado:Buscar control dentro de Listbox.ItemTemplate (WPF C#)

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

Mi doble código de clic:

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

Pero el StackPanel es nulo. ¿Cómo encontrar el derecho TextBlock en SelectedItem?

Gracias por su ayuda.

+0

¿Cómo se vinculen a los ItemsSource de su cuadro de lista? No veo que se establezca en XAML. ¿Hay realmente elementos en su ListBox? Si no, siempre obtendrá un nulo con el código que tiene –

Respuesta

0

Hay una función específica para usar cuando buscas algo cuyo nombre está definido en una plantilla. Pruébelo así:

private void lstTimeline_MouseDoubleClick(object sender, MouseButtonEventArgs e) 
{ 
    ListBoxItem lbi = (lstTimeline.SelectedItem as ListBoxItem); 

    StackPanel item = Template.FindName("stkPanel",lbi) as StackPanel; 
    if (item != null) 
     MessageBox.Show("StackPanel null"); 
    TextBlock textBox = Template.FindName("lblScreenName",item) as TextBlock; 
    if (textBox != null) 
     MessageBox.Show("TextBlock null"); 

    MessageBox.Show(textBox.Text); 
} 
+0

StackPanel devuelve nulo (Valor = nulo) –

+0

Código incompleto. ¿Qué es 'Plantilla'? – GONeale

+0

La plantilla en el código anterior es this.Template, o ListBox.Template - aunque podría ser cualquier objeto con una plantilla. –

0

Linq a xml con un modelo get y set.

var item = ... 

      lstTimeline.SelectedIndex = -1; 
      lstTimeline.ItemsSource = item; 
+1

Lo resolví con esto: http://social.msdn.microsoft.com/forums/en-US/wpf/thread/7d2b4134-e460-4daa-86b7-24a629d77718 –

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

Función FindVisualChild se puede encontrar en la página de MSDN 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; 
} 
+2

Gracias, Simon. Eso funcionó muy bien para mí, pero me llevó bastante tiempo descubrir que "FindVisualChild" es un método que tienes que escribir tú mismo: http://msdn.microsoft.com/en-us/library/bb613579.aspx –

+1

@ BrianSchroer He actualizado la respuesta con su enlace – sergtk

+1

¿El método FindName no está disponible en Windows Phone? –