XAML 中定义的 DataTemplate 具有 null VisualTree

发布于 2024-08-27 07:58:58 字数 1145 浏览 17 评论 0原文

我将 WPF 与 .NET 3.0 一起使用。

我有一个相对简单的 DataTemplate 定义为 GridView 的 CellTemplate。我希望 DataTemplate 的 VisualTree 属性包含 FrameworkElementFactory,但当我尝试从 GridViewColumnHeader.Click 事件访问它时,该属性为 null。为什么 VisualTree 为空?我需要访问它。这是 ListView 定义:

<ListView ItemsSource="{Binding Stuff}" GridViewColumnHeader.Click="Header_Click">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="28">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Image Name="statusImage" Width="16" Height="16" Source="../Images/media_play_green_16x16.png"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

这是事件处理程序:

private void Header_Click(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader gvch = e.OriginalSource as GridViewColumnHeader;

    // error! VisualTree is null!
    //gvch.Column.CellTemplate.VisualTree.GetType(); 
}

I'm using WPF with .NET 3.0.

I have a relatively simple DataTemplate defined as the CellTemplate for a GridView. I expect the DataTemplate's VisualTree property to contain a FrameworkElementFactory, but the property is null when I try to access it from the GridViewColumnHeader.Click event. Why is the VisualTree null? I need to access it. Here is the ListView definition:

<ListView ItemsSource="{Binding Stuff}" GridViewColumnHeader.Click="Header_Click">
    <ListView.View>
        <GridView>
            <GridViewColumn Width="28">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <Image Name="statusImage" Width="16" Height="16" Source="../Images/media_play_green_16x16.png"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

And here is the event handler:

private void Header_Click(object sender, RoutedEventArgs e)
{
    GridViewColumnHeader gvch = e.OriginalSource as GridViewColumnHeader;

    // error! VisualTree is null!
    //gvch.Column.CellTemplate.VisualTree.GetType(); 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独闯女儿国 2024-09-03 07:58:58

这是已知且预期的行为。我现在找不到 MSDN 或其他“权威”引文,但是 此 MSDN 论坛帖子 解释了(有点!):

FrameworkTemplate.VisualTree 属性
...主要用于当您
以编程方式创建
代码中的数据模板/控制模板,
定义时
数据模板/控制模板使用
XAML,该属性将为 null,
因为WPF使用了另一种机制
实例化和构造 XAML
生成的模板。 (强调
添加)

因此,从 XAML 加载模板时不会填充 VisualTree 属性:仅当您使用 FrameworkElementFactory 在代码中构造模板时才会填充它。

要获取 XAML 中定义的模板的内容,请调用 FrameworkTemplate.LoadContent()。这将具体化模板的实例并为您提供根元素——然后您可以根据需要深入研究并设置属性或绑定。不过,您可以将物化实例放入包含窗口或控件的可视化树中,因此您可能需要封装它!

This is the known and expected behaviour. I can't find a MSDN or other "authoritative" citation right now, but this MSDN forums post explains (sort of!):

FrameworkTemplate.VisualTree property
... is mainly used when you
programmatically create
DataTemplate/ControlTemplate in code,
When defining
DataTemplate/ControlTemplate using
XAML, this property will be null,
because WPF uses another mechanism
to instantiate and construct XAML
generated templates
. (emphasis
added)

So the VisualTree property is not populated when a template is loaded from XAML: it is populated only if you construct the template in code using FrameworkElementFactory.

To get the content of a template defined in XAML, call FrameworkTemplate.LoadContent(). This will materialise an instance of the template and give you the root element -- you can then drill in as required and set properties or bindings. It is up to you to slot the materialised instance into the containing window or control's visual tree though, so you will probably want to encapsulate this!

家住魔仙堡 2024-09-03 07:58:58

Visual Tree 为 null 的原因是 Visual Tree 属性更接近于逻辑树,而不是Visual One
模板的实际内容存储在没有公共成员的 TemplateContent 对象中,您必须使用 LoadContent 方法。

The reason behind Of Visual Tree being null is because Visual Tree property is closer to Logical Tree rather than Visual One.
Actual content of the Template is stored in TemplateContent object which has no public members, You will have to use LoadContent method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文