如何使用WPF创建一个层次结构的组合框?

3

我希望在WPF中创建一个层次结构下拉框。 我将绑定下拉框到一个类集合,其结构如下:

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

我希望下拉框看起来像这样:
------------------------
| 文件夹名称                                                                      
|      子文件夹名称  |
|      子文件夹名称  |
|      子文件夹名称  |
----------------------
------------------------
| 文件夹名称           
|      子文件夹名称  |
|      子文件夹名称  |
|      子文件夹名称  |
----------------------
------------------------
| 文件夹名称                                                                       
|      子文件夹名称  |
|      子文件夹名称  |
|      子文件夹名称  |
------------------------
用户应能选择文件夹或子文件夹。
请告诉我如何实现此功能。

1
这是一个嵌套层次结构吗?一个子文件夹可以包含更多的子文件夹吗? - Alex Shtof
2个回答

2
为了让这个内容适应组合框的模型,即一个ItemsControl,它显示离散项目的连续列表,您需要将层次结构压缩为单个列表。
由于我很懒,我会创建一个视图模型,公开PaddingText属性,然后让用于填充视图模型的代码根据每个项目在层次结构中的级别设置Padding。然后我会为组合框创建一个项目模板,它看起来像这样:
<DataTemplate>
   <TextBlock Padding="{Binding Padding}" Text="{Binding Text}"/>
</DataTemplate>

这种方法存在很多缺点。但是它易于构建,并且可以快速让您了解是否真正适合以这种方式呈现信息。


0
我不知道这个解决方案是否适合你的需求,但是:
  1. 创建新的WPF应用程序(例如HierarchicalComboBox),并将下面的代码粘贴到Window1.xaml.cs代码中:

    public partial class Window1 : Window
    {
        public ObservableCollection<Folder> Folders { get; set; }
    
    
    <pre><code>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中粘贴以下代码:

    <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>  
    

解释:

在 Window.Resources 中,我们声明了一个 HierarchicalDataTemplate,它用于将我们的 ViewModel 类(这里是一个 Folder 类)绑定到相应的 View,即 HierarchicalDataTemplate 的内容。

然后在 Window1.xaml 中,我们将其作为一个内容写入 ItemsControl,该控件将承载我们的文件夹列表。

就是这样,你可以在你的解决方案中以类似的方式进行操作。希望这对你有所帮助。如果你有任何问题,请随时留言。

关于格式

对于格式不佳,我很抱歉,但我无能为力。如果你们中有人有编辑答案的能力,请尝试重新格式化代码示例。


你有两个编号为1的点。在第二个点中,只有两行XAML代码,它们本身似乎并不是很有用。你确定没有忘记添加任何重要的内容吗? - Andrei Pana
我部分修复了格式。当您在项目符号/编号列表中发布代码时,需要缩进两次。不过,我不确定C#代码中的尖括号出了什么问题... - Thomas Levesque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接