从TabItem获取并迭代控件?

3
如何获取嵌套在 TabControl 的 TabItem 中的所有控件/UI 元素?
我尝试了一切但都未能获得它们。
(设置 SelectedTab):
    private TabItem SelectedTab = null;
    private void tabControl1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        SelectedTab = (TabItem)tabControl1.SelectedItem;
    }

现在我需要类似这样的东西:
  private StackPanel theStackPanelInWhichLabelsShouldBeLoaded = null;
  foreach (Control control in tabControl.Children /*doesnt exist*/, or tabControl.Items /*only TabItems*/, or /*SelectedTab.Items ??*/ ) //I Have no plan
  {
        if(control is StackPanel)
        {
            theStackPanelInWhichLabelsShouldBeLoaded = control;
            //Load Labels in the Stackpanel, thats works without problems
        }
  }

在Silvermind之后: 这样做,Count始终为1:
        UpdateLayout();
        int nChildCount = VisualTreeHelper.GetChildrenCount(SelectedTab);

选项卡可能需要在呈现其子元素之前首先触发UpdateLayout。例如,当选项卡被选择/打开时会发生这种情况。您需要在呈现其布局后使用SelectedTab,然后是其子元素。 - Silvermind
修改后的答案仍然是1(网格)。 - eMi
3个回答

4

TabControl有一个Items属性(从ItemsControl派生),它返回所有的TabItems - http://msdn.microsoft.com/en-us/library/system.windows.controls.itemscontrol.items.aspx。或者您可以遍历可视树:

var firstStackPanelInTabControl = FindVisualChildren<StackPanel>(tabControl).First();

使用:

public static IEnumerable<T> FindVisualChildren<T>(DependencyObject rootObject) where T : DependencyObject
{
  if (rootObject != null)
  {
    for (int i = 0; i < VisualTreeHelper.GetChildrenCount(rootObject); i++)
    {
      DependencyObject child = VisualTreeHelper.GetChild(rootObject, i);

      if (child != null && child is T)
        yield return (T)child;

      foreach (T childOfChild in FindVisualChildren<T>(child))
        yield return childOfChild;
    }
  }
}

我不需要TabItems,我需要从TabItem本身获取控件/UI元素,这些TabItem嵌套在TabItem或TabControl中。我不知道。 - eMi
然后,您可以始终遍历可视树。我在答案中添加了示例代码。 - Nikolay
很棒的回答。您能详细说明where T : DependencyObject是什么意思吗?或者给我一个查找更多信息的链接? - estebro
“Where T: DependencyObject”是一种泛型类型约束(http://msdn.microsoft.com/en-us/library/bb384067.aspx)。基本上它只是限制类型T必须派生自DependencyObject,所以在方法体中我可以使用需要DependenceObject作为参数的VisualTreeHelper.GetChild。 - Nikolay

2
也许这种方法可以帮助您:
public static IEnumerable<T> FindChildren<T>(this DependencyObject source)
                                             where T : DependencyObject
{
  if (source != null)
  {
    var childs = GetChildObjects(source);
    foreach (DependencyObject child in childs)
    {
      //analyze if children match the requested type
      if (child != null && child is T)
      {
        yield return (T) child;
      }

      //recurse tree
      foreach (T descendant in FindChildren<T>(child))
      {
        yield return descendant;
      }
    }
  }
}

请点击这里查看完整文章(在WPF树中查找元素)。


0

对于选项卡控件,VisualTreeHelper.GetChildrenCount 对我总是返回 0,所以我不得不使用这种方法。

 public static List<T> ObtenerControles<T>(DependencyObject parent)
    where T : DependencyObject
    {
        List<T> result = new List<T>();           
        if (parent != null)
        {
            foreach (var child in LogicalTreeHelper.GetChildren(parent))
            {                   
                var childType = child as T;
                if (childType != null)
                {
                    result.Add((T)child);
                }

                foreach (var other in ObtenerControles<T>(child as DependencyObject))
                {
                    result.Add(other);
                }
            }
        }

        return result;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接