Можно ли связать 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>