2

I need to group my Items in a Combobox like this.

[Category]
- Item
- Item
[Category2]
- Item
- Item

I found an working answer here, but my comboboxes are created dynamically by User Action.
Is it possible to fill the Combobox like this programmatically?

The Items I want to display are ModuleCategoryViewControl's :

public class ClassNameController
{
    public string Name { get; set; }
    public System.Type ObjectType { get; set; }
    public ClassNameController(string name, Type objectType)
    {
        this.Name = name;
        this.ObjectType = objectType;
    }
    public override string ToString()
    {
        return Name;
    }
}
class ModuleCategoryViewControl : ClassNameController
{
    public string Category { get; set; }
    public ModuleCategoryViewControl(string name, string category, Type objectType) : base(name, objectType)
    {
        this.Category = category;
    }
}

They should group by Category and displayed by Name

Community
  • 1
  • 1
itskajo
  • 285
  • 2
  • 19

1 Answers1

1

Is it possible to fill the Combobox like this programmatically?

The sample code on the link you supplied does fill the ComboBox programmatically so it's unclear what your issue really is.

If you add items dynamically at runtime you should replace the List<ModuleCategoryViewControl> with an ObservableCollection<ModuleCategoryViewControl>.

Please refer to the following sample code.

Window.xaml.cs:

public partial class MainWindow : Window
{
    readonly ObservableCollection<ModuleCategoryViewControl> items = new ObservableCollection<ModuleCategoryViewControl>();

    public MainWindow()
    {
        InitializeComponent();

        items.Add(new ModuleCategoryViewControl("Item2", "A", typeof(int)));
        items.Add(new ModuleCategoryViewControl("Item2", "A", typeof(int)));
        items.Add(new ModuleCategoryViewControl("Item3", "A", typeof(int)));
        items.Add(new ModuleCategoryViewControl("Item4", "B", typeof(int)));
        items.Add(new ModuleCategoryViewControl("Item5", "B", typeof(int)));


        ListCollectionView lcv = new ListCollectionView(items);
        lcv.GroupDescriptions.Add(new PropertyGroupDescription("Category"));

        comboBox.ItemsSource = lcv;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        items.Add(new ModuleCategoryViewControl("Item6", "A", typeof(int)));
        items.Add(new ModuleCategoryViewControl("Item7", "C", typeof(int)));
    }
}

Window.xaml:

<StackPanel x:Name="sp">
    <ComboBox x:Name="comboBox">
        <ComboBox.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Name}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ComboBox.GroupStyle>
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>

    <Button Content="Add Item" Click="Button_Click" />

</StackPanel>

If you want to create the DataTemplates programmatically you could use the XamlReader.Parse method:

ComboBox cmb = new ComboBox();
cmb.GroupStyle.Add(System.Windows.Markup.XamlReader.Parse("<GroupStyle xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"><GroupStyle.HeaderTemplate><DataTemplate><TextBlock Text=\"{Binding Name}\"/></DataTemplate></GroupStyle.HeaderTemplate></GroupStyle>") as GroupStyle);
cmb.ItemTemplate = System.Windows.Markup.XamlReader.Parse("<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"><TextBlock Text=\"{Binding Name}\"/></DataTemplate>") as DataTemplate;
cmb.ItemsSource = lcv;

sp.Children.Add(cmb);
mm8
  • 163,881
  • 10
  • 57
  • 88
  • Apparently, I expressed myself unclear. I wanted to create the DataTemplates programmtically :) Your answer worked like a charm. – itskajo Mar 16 '17 at 07:03