Nikhil Vaidya
Nikhil Vaidya

Reputation: 93

How can I create a hierarchical combobox using WPF?

I want to create a hierarchical combobox in WPF. I will be binding the combobox to a collection of class whose structure is given below:

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

And I want the combobox to look like this:

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

The user should be able to select either a folder or a sub-folder.

Please tell me how I can do this.

Upvotes: 3

Views: 4556

Answers (2)

Eugene Cheverda
Eugene Cheverda

Reputation: 8930

I don't know whether or not this solution suits your needs but:

  1. Create new WPF application (HierarchicalComboBox for example) and paste the code below instead of Window1.xaml.cs code:

    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. Then in Window1.xaml paste the code below:

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

Explanation:

In Window.Resources we declared HierarchicalDataTemplate which is to bind our ViewModel class (here it is a Folder class) to corresponding View, which is the content of HierarchicalDataTemplate.

Then in Window1.xaml we write as a content ItemsControl which will host our list of folders.

Thats all, you can do it similarly in your solution. Hope this helps. If you have any questions then welcome to comments.

ABOUT FORMATTING

I'm sorry for poor formatting but can't do anything with, If some of you have an ability to edit answers, please try to re-format the code examples.

Upvotes: 0

Robert Rossney
Robert Rossney

Reputation: 96720

To make this fit into the model of the combo box, which is an ItemsControl that displays a sequential list of discrete items, you're going to need to flatten the hierarchy into a single list.

Because I'm lazy, I'd create a view model that exposes Padding and Text properties, and then have the code that populates the view model set the Padding based on each item's level in the hierarchy. Then I'd create an item template for the combo box that looked like this:

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

There are a lot of shortcomings with this approach. But it's easy to build and it will quickly give you a sense of whether or not this is really the appropriate way to present this information.

Upvotes: 2

Related Questions