【问题标题】:How to access Generated WPF controls after Data Binding数据绑定后如何访问生成的 WPF 控件
【发布时间】:2011-04-16 21:52:10
【问题描述】:

请考虑以下 XAML 代码:

<ListBox Name="listBox1" ItemsSource="{Binding}" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Border Name="border1">
                <TextBlock Text="{Binding}" />
            </Border>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

我们给它分配一个简单的数组:

listBox1.DataContext = new[] { "A", "B", "C" };

现在的问题是我们如何访问为 Border(或 TextBlock 实例)生成的对象?

  • “border1”是不可能的。它不存在。
  • listBox1.ItemContainerGenerator.ContainerFromIndex(0) 返回一个 ListBoxItem,但该 ListBoxItem 的内容是 String 类型。
  • FindName("border1") 返回 null

更新:我希望找到 3 个 Border 实例(和 3 个 TextBlock,每个 Border 一个)。

【问题讨论】:

    标签: wpf xaml binding datatemplate


    【解决方案1】:

    获得 ListBoxItem 后,您需要遍历可视化树以找到您要查找的内容。

    WPF 博士有一些关于它的精彩文章here

    这是该文章中用于搜索特定类型后代的代码

      public static Visual GetDescendantByType(Visual element, Type type)
      {
          if (element.GetType() == type) return element;
    
          Visual foundElement = null;
    
          if (element is FrameworkElement)
              (element as FrameworkElement).ApplyTemplate();
    
          for (int i = 0;
              i < VisualTreeHelper.GetChildrenCount(element); i++)
          {
              Visual visual = VisualTreeHelper.GetChild(element, i) as Visual;
              foundElement = GetDescendantByType(visual, type);
              if (foundElement != null)
                  break;
          }
    
          return foundElement;
      }
    

    【讨论】:

    • 但是,我只想指出 WPF 博士还指出,很少需要以这种方式操作可视化树。几乎有更多“正确”(可靠和/或有弹性)的方法可以做任何事情。
    • 不幸的是,这不是答案:我正在寻找的是“实例”或边框,它们不是在 ItemTemplate 中生成的。在这里,我希望找到“3”个 Border 类型的对象(我在 DataContext 中有 3 个项目)
    • @shayan:遍历可视化树将为您获取所需的实例数据。只需使用 listview 作为 Visual 和 Border 作为类型。但就像亚历克斯建议的那样,他们通常是一种更好的方法。拿到 Border 后你想做什么?
    • 这个问题实际上是为了解决这里解释的情况而提出的:stackoverflow.com/questions/3802102/…
    【解决方案2】:

    你可以这样访问它:

            DataTemplate dt = this.listBox1.ItemTemplate;
            Border border = dt.LoadContent() as Border;
            // Do something with border...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 2015-07-07
      • 1970-01-01
      相关资源
      最近更新 更多