Treeview SelectedItem иногда является виртуальной машиной, а иногда TreeViewItem.

У меня есть TreeView, по которому пользователь перемещается, чтобы выбрать элемент для отображения в сетке. Вкратце XAML выглядит так:

    <local:TreeViewEx x:Name="theTreeView" ItemsSource="{Binding theData}">

                        <local:TreeViewEx.ItemTemplate>
                            <sdk:HierarchicalDataTemplate ItemsSource="{Binding theChildData}">
                                <TextBlock Text="{Binding Name}"/>
                            </sdk:HierarchicalDataTemplate>
                        </local:TreeViewEx.ItemTemplate>
                    </local:TreeViewEx>

 <Grid DataContext="{Binding ElementName=theTreeView, Path=SelectedItem}">
                            <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding}" />
                    <TextBlock Text="{Binding Name}" /></StackPanel>
        </Grid>

Когда пользователь щелкает древовидную структуру, имя типа модели представления отображается вместе со значением свойства Name. Идеально. Однако пользователь также может выполнить поиск в древовидной структуре (после Джоша Смита ), который задает свойство IsSelected элемента TreeViewItem. Как только это происходит, {Binding} отображает TreeViewItemEx, а не имя типа ViewModel, и, конечно же, свойство Name не отображается.

Как это возможно, что selectedItem иногда будет ViewModel, а иногда будет TreeViewItem?


person Ralph Shillington    schedule 09.09.2010    source источник


Ответы (1)


Если вы замените сетку на ContentControl, вы сможете использовать DataTemplateSelector.

<ContentControl Content="{Binding ElementName=theTreeView, Path=SelectedItem}" 
                ContentTemplateSelector="{StaticResource TreeViewItemSelector}" />

Затем на DataTemplateSelector вы можете ссылаться на два шаблона для разных типов.

    <DataTemplate x:Key="ModelTemplate">
        <StackPanel Orientation="Vertical">
            <TextBlock Text="{Binding}" />
            <TextBlock Text="{Binding Name}" />
        </StackPanel>
    </DataTemplate>

    <TreeViewItemSelector x:Key="TreeViewItemSelector"
                          ModelTemplate="{StaticResource ModelTemplate}"
                          TreeItemTemplate="{StaticResource TreeItemTemplate}" />

В селекторе вам понадобится такая логика

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item is ModelType)
            return ModelTemplate;
        if (item is TreeViewItem)
            return TreeItemTemplate;
        throw new NotImplementedException();
    }
person Tom Dudfield    schedule 16.02.2011
comment
Вопрос помечен Silverlight, и, если я не ошибаюсь, ContentTemplateSelector недоступен в Silverlight. - person Ralph Shillington; 16.02.2011
comment
Моя способность перечитывать вещи до сих пор поражает меня. Существует несколько примеров создания эквивалента для Silverlight - person Tom Dudfield; 16.02.2011