Cómo: Buscar elementos generados por un objeto DataTemplate

Actualización: noviembre 2007

En este ejemplo se muestra cómo buscar elementos generados por un objeto DataTemplate.

Ejemplo

En este ejemplo, hay un control ListBox enlazado a algunos datos XML:

<ListBox Name="myListBox" ItemTemplate="{StaticResource myDataTemplate}"
         IsSynchronizedWithCurrentItem="True">
  <ListBox.ItemsSource>
    <Binding Source="{StaticResource InventoryData}" XPath="Books/Book"/>
  </ListBox.ItemsSource>
</ListBox>

El control ListBox utiliza el siguiente objeto DataTemplate:

<DataTemplate x:Key="myDataTemplate">
  <TextBlock Name="textBlock" FontSize="14" Foreground="Blue">
    <TextBlock.Text>
      <Binding XPath="Title"/>
    </TextBlock.Text>
  </TextBlock>
</DataTemplate>

Si desea recuperar el elemento TextBlock generado por el objeto DataTemplate de un elemento ListBoxItem determinado, debe obtener el elemento ListBoxItem, hallar el objeto ContentPresenter contenido en ese ListBoxItem y, a continuación, llamar al método FindName del objeto DataTemplate establecido para ese objeto ContentPresenter. En el ejemplo siguiente se muestra cómo realizar estos pasos. Con fines de demostración, en este ejemplo se crea un cuadro de mensaje que muestra el contenido de texto de DataTemplate, el bloque de texto generado.

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

A continuación se muestra la implementación de FindVisualChild, que utiliza los métodos de VisualTreeHelper:

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

Para obtener el ejemplo completo, vea Ejemplo Finding Template-Generated Elements.

Vea también

Tareas

Cómo: Buscar elementos generados por un objeto ControlTemplate

Conceptos

Información general sobre el enlace de datos

Aplicar estilos y plantillas

Ámbitos de nombres de WPF

Árboles en WPF

Otros recursos

Ejemplos de enlace de datos

Temas "Cómo..." sobre enlace de datos