带有层次结构/树视图的ListBox

时间:2014-02-09 09:47:56

标签: c# wpf xaml user-controls tree

我的域由层次结构组成,我想将其显示给用户并允许选择节点。

我所寻求的是一种将列表框与树视图混合的方法,就像在资源管理器的导航栏中一样。

Windows Explorer's Navigation

这样做的优雅方法是什么?

根节点(可以扩展的节点)应该是可选择的,就像目录在Windows资源管理器中一样

我的域名(和视图模型)看起来像这样:

interface INode
{
    String Title { get; set; } // The header
    IEnumerable<Node> SubNodes { get; }

    // Some other irrelevant stuff

}

2 个答案:

答案 0 :(得分:1)

有一种优雅的方式来做到这一点。使用Object图和HierarchicalDataTemplate填充TreeView。我通常不鼓励在Xaml中使用名称,但这是使生活变得简单的一种解决方案。

给TreeView一个x:Name(永远不要使用Name,因为并非所有控件都支持它)并将Listbox或ListView的ItemsSource绑定到

{Binding ElementName=TreeViewName, Path=SelectedItem.SubNotes}

所以你的Xaml会读到类似的内容。

<Window x:Class="StackOverflow._21657576.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:this="clr-namespace:StackOverflow._21657576"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <HierarchicalDataTemplate DataType="{x:Type this:Node}" ItemsSource="{Binding Path=SubNodes}">
            <TextBlock Text="{Binding Path=Title}" />
        </HierarchicalDataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>

        <TreeView x:Name="MyTreeView" ItemsSource="{Binding Path=Nodes}" />
        <ListView ItemsSource="{Binding ElementName=MyTreeView, Path=SelectedItem.SubNodes}" Grid.Column="1" />
    </Grid>
</Window>

我已将Node类更改为

public class Node
{
    public String Title { get; set; } // The header
    public ObservableCollection<Node> SubNodes { get; set; }
}

ViewModel上的Nodes属性是

public ObservableCollection<Node> Nodes { get; set; }

如果提供了有效的Node对象集合,则此XAML将起作用。

我希望这会有所帮助。

答案 1 :(得分:0)

我建议您自己构建此控件,只需使用ItemsControl和DataTemplates。

例如:

<ItemsControl ItemsSource="{Binding Nodes}">
    <ItemsControl.ItemTemplate>
        <DataTemplate DataType="vm:Node">
            <StackPanel>
            <TextBlock Text="{Binding Title}" />
            <ItemsControl ItemsSource="{Binding SubNodes}">
                 <ItemsControl.ItemTemplate>
                      <!-- Specify template for subnodes here -->
                 </ItemsControl.ItemTemplate>
            </ItemsControl>
            </Stackpanel>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

我认为您可以在此基础上进行定制并根据您的需求进行定制。在上面的例子中,没有任何东西可以选择。使用ItemsSource和没有ItemContainerStyle实现此行为的方法有很多种。

一种方法是使用列表框,而不是外部ItemsControl,并在{{1}}中设置自定义控件模板。我希望这能让你前进,请继续询问是否没有。祝你好运!