情况2:当没有设定DataTemplate的Name或是以Resource方式调用时,获取DataTemplate里的指定控件。


方法:

1、这里需要有一个从DataTemplate里获取控件的函数


  1. public T FindFirstVisualChild<T>(DependencyObject obj, string childName) where T : DependencyObject
  2. {
  3. for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
  4. {
  5. DependencyObject child = VisualTreeHelper.GetChild(obj, i);
  6. if (child != null && child is T && child.GetValue(NameProperty).ToString() == childName)
  7. {
  8. return (T)child;
  9. }
  10. else
  11. {
  12. T childOfChild = FindFirstVisualChild<T>(child, childName);
  13. if (childOfChild != null)
  14. {
  15. return childOfChild;
  16. }
  17. }
  18. }
  19. return null;
  20. }


2、 ​


  1. <ItemsControl x:Name="itemsControl" Background="#B28BB2F1">
  2. <ItemsControl.ItemsPanel>
  3. <ItemsPanelTemplate>
  4. <WrapPanel Orientation="Horizontal"/>
  5. </ItemsPanelTemplate>
  6. </ItemsControl.ItemsPanel>
  7. <ItemsControl.ItemTemplate>
  8. <DataTemplate>
  9. <Border Padding="3">
  10. <WrapPanel>
  11. <TextBox x:Name="txtID"/>
  12. <TextBlock x:Name="txtName" Text="Good"/>
  13. </WrapPanel>
  14. </Border>
  15. </DataTemplate>
  16. </ItemsControl.ItemTemplate>
  17. </ItemsControl>


或者


  1. <Page.Resource>
  2. <DataTemplate x:Key="data">
  3. <Border Padding="3">
  4. <WrapPanel>
  5. <TextBox x:Name="txtID"/>
  6. <TextBlock x:Name="txtName" Text="Good"/>
  7. </WrapPanel>
  8. </Border>
  9. </DataTemplate>
  10. </Page.Resources>

  11. <ItemsControl x:Name="itemsControl" Background="#B28BB2F1" ItemTemplate="{StaticResource data}">
  12. <ItemsControl.ItemsPanel>
  13. <ItemsPanelTemplate>
  14. <WrapPanel Orientation="Horizontal"/>
  15. </ItemsPanelTemplate>
  16. </ItemsControl.ItemsPanel>
  17. </ItemsControl>


3、解下来就写按钮的处理函数:


我需要获取DataTemplate里名为"txtName"的TextBlock控件并显示他的Text内容。

private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { TextBlock txt = FindFirstVisualChild<TextBox>(itemsControl, "txtName"); if (txt != null)//判断是否找到 MessageBox.Show(txt.Text.ToString()); }




情况3:当没有设定DataTemplate的里的控件Name或者你压根不知道里面有哪些控件,但是你又想获取他们的值时。例如上一篇,当我动态生成CheckBox后,我想知道哪些CheckBox被选中了。



方法:

1、也需要一个获取DataTemplate控件的函数,但是返回的是一个集合。 ​


  1. public List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
  2. {
  3. DependencyObject child = null;
  4. List<T> childList = new List<T>();
  5. for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
  6. {
  7. child = VisualTreeHelper.GetChild(obj, i);
  8. if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name)))
  9. {
  10. childList.Add((T)child);
  11. }
  12. childList.AddRange(GetChildObjects<T>(child, ""));//指定集合的元素添加到List队尾
  13. }
  14. return childList;
  15. }


2、xaml中代码(详细请看前一篇) ​


  1. <ItemsControl x:Name="itemsControl" Background="#B28BB2F1">
  2. <ItemsControl.ItemsPanel>
  3. <ItemsPanelTemplate>
  4. <WrapPanel Orientation="Horizontal"/>
  5. </ItemsPanelTemplate>
  6. </ItemsControl.ItemsPanel>
  7. <ItemsControl.ItemTemplate>
  8. <DataTemplate>
  9. <Border Padding="3">
  10. <WrapPanel>
  11. <CheckBox Content="{Binding txt}"/>
  12. </WrapPanel>
  13. </Border>
  14. </DataTemplate>
  15. </ItemsControl.ItemTemplate>
  16. </ItemsControl>


3、解下来就写按钮的处理函数

  1. private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
  2. {
  3. DataVisualTreeHelper VTHelper = new DataVisualTreeHelper();
  4. List<CheckBox> collection = VTHelper.GetChildObjects<CheckBox>(itemsControl, "")//第2个参数为空,表示查找所有指定类型的控件(返回

  5. 一个CheckBox集合)
  6. foreach (CheckBox item in collection //遍历这个集合
  7. {
  8. if (item.IsChecked == true)
  9. MessageBox.Show(item.Content.ToString() + "被选中了!");
  10. }
  11. }