DataTemplate, определенный в XAML, имеет нулевое VisualTree - PullRequest
4 голосов
/ 31 марта 2010

Я использую WPF с .NET 3.0.

У меня относительно простой DataTemplate, определенный как CellTemplate для GridView. Я ожидаю, что свойство VisualTree объекта DataTemplate будет содержать 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(); 
}

Ответы [ 2 ]

6 голосов
/ 31 марта 2010

Это известное и ожидаемое поведение. Я не могу найти MSDN или другую «авторитетную» цитату прямо сейчас, но это сообщение на форуме MSDN объясняет (вроде!):

FrameworkTemplate.VisualTree свойство ... в основном используется, когда вы программно создать DataTemplate / ControlTemplate в коде, При определении DataTemplate / ControlTemplate с использованием XAML, это свойство будет нулевым, потому что WPF использует другой механизм создать экземпляр и построить XAML сгенерированные шаблоны . (курсив добавлено)

Таким образом, свойство VisualTree не заполняется при загрузке шаблона из XAML: оно заполняется только в том случае, если шаблон создается в коде с использованием FrameworkElementFactory.

Чтобы получить содержимое шаблона, определенного в XAML, вызовите FrameworkTemplate.LoadContent (). Это материализует экземпляр шаблона и даст вам корневой элемент - затем вы сможете развернуть его по мере необходимости и установить свойства или привязки. Вы можете вставить материализованный экземпляр в содержащее окно или визуальное дерево элемента управления, так что вы, вероятно, захотите инкапсулировать это!

0 голосов
/ 21 апреля 2015

Причина того, что Visual Tree является нулевым, заключается в том, что свойство Visual Tree ближе к Логическое дерево , а не Visual One . Фактическое содержимое шаблона хранится в TemplateContent объекте, который не имеет открытых членов. Вам нужно будет использовать LoadContent метод.

...