如何查找 ControlTemplate 生成的元素 - 排除 FindName()

How to find ControlTemplate-Generated Element - FindName() excluded

提问人:user947737 提问时间:11/14/2023 更新时间:11/15/2023 访问量:59

问:

我有一个精心设计的自定义控件,它根据其 ContentTemplate 创建的控件类型更改其分析内容的方式。我不能依赖于模板中给出的名称(其他人的用法),因此 Template.FindName 将无法正常工作,如以下示例所示:Microsoft Learn。我在搜索中没有找到可用的答案,因为所有结果都指向链接示例中的解决方案。使用 VisualTreehelper 意味着知道模板包含的内容,所以这不是这个想法。

以这个 ContentTemplate 为例,我需要获取 ListBox 的实例。

<DataTemplate x:Key="MyKey">
<ListBox>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding X}" />
                <TextBlock Text="{Binding Y}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

有什么想法吗?

C# .NET WPF

评论

2赞 Clemens 11/14/2023
"使用 VisualTreehelper 意味着知道模板包含什么“——为什么呢?只需获取控件的 ContentPresenter 的直接可视子级。
0赞 MIHOW 11/14/2023
这是一个棘手的解决方案,但有时为了找到嵌套在其他控件的模板深处的控件,可以使用该控件的事件(在您的情况下为 ListBox)。Loaded

答:

0赞 user947737 11/15/2023 #1

多亏了对这个问题的评论与这篇文章相结合的推动,我设法解决了这个问题:

ContentPresenter 的直接视觉子项是 ContentControl 的第一个子项,这就是我要寻找的。

我覆盖了 OnApplytemplate 以实现我的目标,正如帖子所示,由于我不明显的原因,ContentPresenter 必须依次应用其模板,否则它仍然是空的。

ContentTemplate.LoadContent() 也很有用,但提供了不同的实例,因此它仅在您追求 Type 时才有用。