Reputation: 93
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
Reputation: 8930
I don't know whether or not this solution suits your needs but:
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<Folder>
{
new Folder()
{
Name = "First",
SubFolders =
new ObservableCollection<Folder>
{
new Folder() {Name = "FirstFolderFirstSub"},
new Folder() {Name = "FirstFolderSecondSub"},
new Folder() {Name = "FirstFolderThirdSub"}
}
},
new Folder()
{
Name = "Second",
SubFolders =
new ObservableCollection<Folder>
{
new Folder() {Name = "SecondFolderFirstSub"},
new Folder() {Name = "SecondFolderSecondSub"},
new Folder() {Name = "SecondFolderThirdSub"}
}
}
};
Folders = new ObservableCollection<Folder>(folders);
InitializeComponent();
DataContext = this;
}
}
public class Folder
{
public string Name { get; set; }
public ObservableCollection<Folder> SubFolders { get; set; }
}
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
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