4

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

我有一个相对简单的 DataTemplate 定义为 GridView 的 CellTemplate。我希望 DataTemplate 的 VisualTree 属性包含一个 FrameworkElementFactory,但是当我尝试从 GridViewColumnHeader.Click 事件访问它时,该属性为空。为什么 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(); 
}
4

2 回答 2

7

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

FrameworkTemplate.VisualTree 属性 ... 主要用于在代码中以编程方式创建 DataTemplate/ControlTemplate 时,使用 XAML 定义 DataTemplate/ControlTemplate 时,该属性将为 null,因为WPF 使用另一种机制来实例化和构造 XAML 生成的模板(重点补充)

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

若要获取在 XAML 中定义的模板的内容,请调用 FrameworkTemplate.LoadContent()。这将实现模板的一个实例并为您提供根元素——然后您可以根据需要进行深入研究并设置属性或绑定。但是,将物化实例插入包含窗口或控件的可视化树取决于您,因此您可能想要封装它!

于 2010-03-30T23:14:32.373 回答
0

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

于 2015-04-21T07:34:47.183 回答