Можно ли связать WPF TreeView с одним корнем node?

Скажем, у меня есть двоичное дерево, где корень структуры данных - это просто дерево node. Для каждого node дети доступны через свойство Children. Вот что я пробовал. TreeRoot является свойством наследуемого контекста данных, но он представляет собой единственный node (а не набор).

<UserControl.Resources>
    <HierarchicalDataTemplate x:Key="TreeNodeTemplate" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
</UserControl.Resources>

<Grid>
    <TreeView ItemsSource="{Binding TreeRoot}" ItemTemplate="{StaticResource TreeNodeTemplate}" />
</Grid>

Ответы

Ответ 1

У меня была эта проблема, и я пришел к выводу, что я не могу привязать не-коллекцию к древовидному представлению как способ указать корень node. Итак, я сделал быстрый переход к моему ModelView и сделал свойство, представляющее корень node набор из 1 элемента.

public class ContainerViewModel
{
   public ObservableCollection<TreeNodeViewModel> RootNodes { get; private set; }

   public ContainerViewModel()
   {
      // Create a single node in the collection of root nodes
      RootNodes = new ObservableCollection<TreeNodeViewModel>();
      RootNodes.Add(new TreeNodeViewModel());
   }
}

public class TreeNodeViewModel
{
   public ObservableCollection<TreeNodeViewModel> Children { get; set; }
}

Я использовал ObservableCollection < > выше, но может иметь смысл использовать что-то более дешевое, например List < > , поскольку вы не ожидаете изменения коллекции (по крайней мере, в вашем сценарии).

Ответ 2

Я думаю, ваша проблема в том, что ваш иерархический шаблон данных применяется только к корневому node, поэтому вы никогда не увидите ничего из корневых детей. Вместо этого попробуйте:

<UserControl.Resources>
    <HierarchicalDataTemplate DataType="{x:Type TreeNode}" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
</UserControl.Resources>

<Grid>
    <TreeView ItemsSource="{Binding TreeRoot}"/>
</Grid>

Где TreeNode - это имя вашего дерева node.

Ответ 3

Как сказал Авиад, если вы используете DataType="{x:Type TreeNode}", то TreeView автоматически будет использовать этот шаблон для любого объекта этого типа.

Если у вас есть несколько типов в вашей иерархии, вы можете указать несколько HierarchicalDataTemplates, каждый из которых имеет тип данных, для которого он предназначен. Это позволило бы TreeView обрабатывать каждый тип по-разному.

<HierarchicalDataTemplate DataType="{x:Type TreeNode}" ItemsSource="{Binding Children}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

<HierarchicalDataTemplate DataType="{x:Type TreeLeaf}">
    <TextBlock Text="{Binding Message}" Background="Red" />
</HierarchicalDataTemplate>