如何使用WPF创建分层组合框?

时间:2010-12-27 10:41:37

标签: wpf combobox wpf-controls

我想在WPF中创建一个分层组合框。我将把组合框绑定到一个类的集合,其结构如下:

Public Class Folder                 
{     
  Public string Name;            
  Public string Path;           
  List<SubFolder> SubFolder;   
}

我希望组合框看起来像这样:

------------------------
| Folder.Name                                                                      
|      SubFolder.Name  |
|      SubFolder.Name  |
|      SubFolder.Name  |
----------------------
------------------------
| Folder.Name           
|      SubFolder.Name  |
|      SubFolder.Name  |
|      SubFolder.Name  |
----------------------
------------------------
| Folder.Name                                                                       
|      SubFolder.Name  |
|      SubFolder.Name  |
|      SubFolder.Name  |
------------------------

用户应该能够选择文件夹或子文件夹。

请告诉我如何做到这一点。

2 个答案:

答案 0 :(得分:2)

为了使其适合组合框的模型,即显示离散项的顺序列表的ItemsControl,您需要将层次结构展平为单个列表。

因为我很懒,我会创建一个公开PaddingText属性的视图模型,然后让填充视图模型的代码设置Padding基于层次结构中每个项目的级别。然后我将为组合框创建一个项目模板,如下所示:

<DataTemplate>
   <TextBlock Padding="{Binding Padding}" Text="{Binding Text}"/>
</DataTemplate>

这种方法存在许多缺点。但它很容易构建,它会很快让您了解这是否真的是提供此信息的适当方式。

答案 1 :(得分:0)

我不知道这个解决方案是否适合您的需求,但是:

  1. 创建新的WPF应用程序(例如HierarchicalComboBox)并粘贴下面的代码而不是Window1.xaml.cs代码:

    public partial class Window1 : Window
    {
        public ObservableCollection<Folder> Folders { get; set; }
    
    
    
    public Window1()
    {
        var folders = new List&lt;Folder&gt;
                      {
                        new Folder()
                          {
                            Name = "First",
                            SubFolders =
                              new ObservableCollection&lt;Folder&gt;
                                {
                                  new Folder() {Name = "FirstFolderFirstSub"},
                                  new Folder() {Name = "FirstFolderSecondSub"},
                                  new Folder() {Name = "FirstFolderThirdSub"}
                                }
                          },
                          new Folder()
                          {
                            Name = "Second",
                            SubFolders =
                              new ObservableCollection&lt;Folder&gt;
                                {
                                  new Folder() {Name = "SecondFolderFirstSub"},
                                  new Folder() {Name = "SecondFolderSecondSub"},
                                  new Folder() {Name = "SecondFolderThirdSub"}
                                }
                          }
                      };
      Folders = new ObservableCollection&lt;Folder&gt;(folders);
      InitializeComponent();
      DataContext = this;
    
    
    }
    
    } public class Folder { public string Name { get; set; } public ObservableCollection<Folder> SubFolders { get; set; } }
  2. 然后在Window1.xaml中粘贴以下代码:

    public Window1()
    {
        var folders = new List&lt;Folder&gt;
                      {
                        new Folder()
                          {
                            Name = "First",
                            SubFolders =
                              new ObservableCollection&lt;Folder&gt;
                                {
                                  new Folder() {Name = "FirstFolderFirstSub"},
                                  new Folder() {Name = "FirstFolderSecondSub"},
                                  new Folder() {Name = "FirstFolderThirdSub"}
                                }
                          },
                          new Folder()
                          {
                            Name = "Second",
                            SubFolders =
                              new ObservableCollection&lt;Folder&gt;
                                {
                                  new Folder() {Name = "SecondFolderFirstSub"},
                                  new Folder() {Name = "SecondFolderSecondSub"},
                                  new Folder() {Name = "SecondFolderThirdSub"}
                                }
                          }
                      };
      Folders = new ObservableCollection&lt;Folder&gt;(folders);
      InitializeComponent();
      DataContext = this;
    
    
    }
    
  3. 说明:

    在Window.Resources中,我们声明了<Window x:Class="HierarchicalComboBox.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:HierarchicalComboBox="clr-namespace:HierarchicalComboBox" Title="Window1"> <Window.Resources> <HierarchicalDataTemplate DataType="{x:Type HierarchicalComboBox:Folder}"> <StackPanel> <TextBlock Text="{Binding Name}"/> <ComboBox Margin="8,0,0,0" ItemsSource="{Binding SubFolders}"/> </StackPanel> </HierarchicalDataTemplate> </Window.Resources> <Grid> <ItemsControl x:Name="HierarchicalComboBox" ItemsSource="{Binding Folders}" VerticalAlignment="Top"> </ItemsControl> </Grid> </Window> ,它将我们的ViewModel类(这里是HierarchicalDataTemplate类)绑定到相应的View,这是Folder的内容。

    然后在Window1.xaml中,我们写为内容HierarchicalDataTemplate,它将托管我们的文件夹列表。

    多数民众赞成,你可以在你的解决方案中做同样的事情。希望这可以帮助。如果您有任何问题,欢迎提出意见。

    关于格式化

    我很抱歉格式不佳但无法执行任何操作,如果有些人能够编辑答案,请尝试重新格式化代码示例。