Question

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(); 
}
Was it helpful?

Solution

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!

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top