如何获取ContentPresenter的子元素?

27

通过这段代码,我可以得到一个内容呈现器。我想要找到它内部的第一个文本框,并将焦点设置在该文本框上。

Dim obj = TerritoryListViewer.ItemContainerGenerator.ContainerFromItem(myModel)
4个回答

31
你可以使用 VisualTreeHelper 静态类来遍历控件树。以下是在 c# 中实现的方法(抱歉我有 VB 识别障碍):
 T FindFirstChild<T>(FrameworkElement element) where T: FrameworkElement
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(element);
        var children = new FrameworkElement[childrenCount];

        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;
            children[i] = child;
            if (child is T)
                return (T)child;
        }

        for (int i = 0; i < childrenCount; i++)
            if (children[i] != null)
            {
                var subChild = FindFirstChild<T>(children[i]);
                if (subChild != null)
                    return subChild;
            }

        return null;
    }

3
这适用于大多数框架元素,但对于ContentPresenter来说却不起作用。 - John Melville
2
@John:听起来很奇怪。那么问题到底是什么?你是无法在树中找到ContentPresenter,还是无法找到ContentPresenter的子元素?可能是因为当你搜索可视树时,它尚未构建好? - alpha-mouse
2
@ Alpha-mouse:你说对了!我正在向列表中添加一个元素,然后立即尝试将焦点放在其中的一个控件上。使用调度程序将焦点操作安排到后台优先级可以解决我的问题。 - John Melville
在第一行的T前面添加public static以使其编译,然后它对我起作用了。 - Chris Arbogast

20

ContentPresenter 只有一个子元素。你可以通过以下方式获取这个子元素

VisualTreeHelper.GetChild(yourContentPresenterObj, 0);

如果你需要深入到第一个找到的TextBox,那么是的,你需要使用@alpha-mouse建议的更全面的方法。


3
Dim myContentPresenter = CType(obj, ContentPresenter)
Dim myDataTemplate = myContentPresenter.ContentTemplate
Dim target = CType(myDataTemplate.FindName("txtQuantity", myContentPresenter), TextBox)

0
在我的情况下,我需要迭代自定义画布中放置的特定基础类型的所有控件,该画布被用于ItemsControl内部。
以下Linq表达式用于从MeasureOverride()中获取这些控件:
var foobarControls =
    InternalChildren
    .OfType<ContentPresenter>()
    .Where(c => VisualTreeHelper.GetChildrenCount(c) > 0)
    .Select(c => VisualTreeHelper.GetChild(c, 0))
    .OfType<FoobarControlBase>();

这可以防止ContentPresenter没有子元素的情况。我发现在某些情况下,根据调用时间,可能尚未建立可视树,因此ContentPresenters将没有子元素。(实际上,这种情况本身可能是一个错误,但无论如何,这段代码被证明是可靠的。)

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