如何:查找由 DataTemplate 生成的元素

更新:2007 年 11 月

下面的示例演示如何查找由 DataTemplate 生成的元素。

示例

在本示例中,有一个绑定到某些 XML 数据的 ListBox

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

ListBox 使用以下 DataTemplate

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

如果要检索由某个 ListBoxItemDataTemplate 生成的 TextBlock 元素,您需要获得 ListBoxItem,在该 ListBoxItem 内查找 ContentPresenter,然后对在该 ContentPresenter 上设置的 DataTemplate 调用 FindName。下面的示例演示如何执行这些步骤。出于演示的目的,本示例创建一个消息框,用于显示由 DataTemplate 生成的文本块的文本内容。

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

下面是 FindVisualChild 的实现,使用的是 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;
}

有关完整示例,请参见 查找由模板生成的元素的示例

请参见

任务

如何:查找由 ControlTemplate 生成的元素

概念

数据绑定概述

样式设置和模板化

WPF 名称范围

WPF 中的树

其他资源

数据绑定示例

数据绑定帮助主题