locked
Binding Two Collections to One Combobox RRS feed

  • Question

  • Hello,

    I want to bind two different Collections to the same combobox at the same time. Each set needs to have a header obove the group. But I can not find a way to get this to work properly. It should look like the following.


    Set one

      frist item set one
      second item set one

    Set two

      first item set two

      second item set two




    This must be done in a combobox, i hope you can help with this

    Wednesday, April 22, 2009 2:05 PM

Answers

  • Hi,

     

    As far as I know, in order to achieve the group style for a ItemsControl, the data should be in the same collection view. Not in a CompositeCollection which composite the two(or more) different collections. If you want to create group in the same collection, you can handily use the CollectionViewSource like this:

     

    <CollectionViewSource x:Key="CollectionPerson"

                                  Source="{StaticResource perserCollectionKey}">

        <CollectionViewSource.GroupDescriptions>

            <dat:PropertyGroupDescription PropertyName="ID" />

        </CollectionViewSource.GroupDescriptions>

    </CollectionViewSource>

     

    And then set the GroupStyle:

    <GroupStyle>

        <GroupStyle.ContainerStyle>

            <Style TargetType="{x:Type GroupItem}">

                <Setter Property="Margin" Value="0,0,0,5"/>

                <Setter Property="Template">

                    <Setter.Value>

                        <ControlTemplate TargetType="{x:Type GroupItem}">

                            <!--your visual respresentation here-->

                        </ControlTemplate>

                    </Setter.Value>

                </Setter>

            </Style>

        </GroupStyle.ContainerStyle>

    </GroupStyle>

     

    If you really want to achieve the layout like you provided, you can set two ListBoxs in the ComboBox, and bind the collection to each ListBox respectively. The following is a small exampel.

     

    XAML code:

    <Window x:Class="WpfComboBoxTest.Window6"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:local="clr-namespace:WpfComboBoxTest"

       xmlns:dat="clr-namespace:System.Windows.Data;assembly=PresentationFramework"

        Title="Window6" Height="300" Width="300">

        <Window.Resources>

            <local:PersonCollection x:Key="perserCollectionKey" />

            <local:AnimalCollection x:Key="animalCollectionKey" />

            <!--Person-->

            <DataTemplate DataType="{x:Type local:Person}">

                <Border>

                    <TextBlock Text="{Binding Name}"  />

                </Border>

            </DataTemplate>

            <!--Animal-->

            <DataTemplate DataType="{x:Type local:Animal}">

                <Border>

                    <TextBlock Text="{Binding Description}"  />

                </Border>

            </DataTemplate>

        </Window.Resources>

        <StackPanel>

            <ComboBox  Name="comboBox">

                <Grid>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition />

                        <ColumnDefinition />

                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>

                        <RowDefinition />

                        <RowDefinition />

                        <RowDefinition />

                        <RowDefinition />

                    </Grid.RowDefinitions>

                    <TextBlock Text="Person collection"  Grid.Row="0" Grid.Column="0" />

                    <TextBlock Text="Person collection"  Grid.Row="2" Grid.Column="0" />

                    <ListBox ItemsSource="{Binding Source={StaticResource perserCollectionKey}}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"  />

                    <ListBox ItemsSource="{Binding Source={StaticResource animalCollectionKey}}" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"   />

                </Grid>

            </ComboBox>

        </StackPanel>

    </Window>

     

    In the code behind:
    using System.Windows;

    using System.Collections.ObjectModel;

    namespace WpfComboBoxTest

    {

        public partial class Window6 : Window

        {

            public Window6()

            {

                InitializeComponent();

            }

        }

        public class PersonCollection : ObservableCollection<Person>

        {

            public PersonCollection()

            {

                this.Add(new Person() { Name = "Person1", ID = "Person" });

                this.Add(new Person() { Name = "Person2", ID = "Person" });

            }

        }

        public class AnimalCollection : ObservableCollection<Animal>

        {

            public AnimalCollection()

            {

                this.Add(new Animal() { Description = "Animal1", ID = "Animal" });

                this.Add(new Animal() { Description = "Animal2", ID = "Animal" });

            }

        }

        public class Person

        {

            public string Name { get; set; }

            public string ID { get; set; }

        }

        public class Animal 

        {

            public string Description { get; set; }

            public string ID { get; set; }

        }

    }

     

    Hope this helps.

    Thanks.

     

    Tuesday, April 28, 2009 7:49 AM

All replies

  • Hi,

     

    As far as I know, in order to achieve the group style for a ItemsControl, the data should be in the same collection view. Not in a CompositeCollection which composite the two(or more) different collections. If you want to create group in the same collection, you can handily use the CollectionViewSource like this:

     

    <CollectionViewSource x:Key="CollectionPerson"

                                  Source="{StaticResource perserCollectionKey}">

        <CollectionViewSource.GroupDescriptions>

            <dat:PropertyGroupDescription PropertyName="ID" />

        </CollectionViewSource.GroupDescriptions>

    </CollectionViewSource>

     

    And then set the GroupStyle:

    <GroupStyle>

        <GroupStyle.ContainerStyle>

            <Style TargetType="{x:Type GroupItem}">

                <Setter Property="Margin" Value="0,0,0,5"/>

                <Setter Property="Template">

                    <Setter.Value>

                        <ControlTemplate TargetType="{x:Type GroupItem}">

                            <!--your visual respresentation here-->

                        </ControlTemplate>

                    </Setter.Value>

                </Setter>

            </Style>

        </GroupStyle.ContainerStyle>

    </GroupStyle>

     

    If you really want to achieve the layout like you provided, you can set two ListBoxs in the ComboBox, and bind the collection to each ListBox respectively. The following is a small exampel.

     

    XAML code:

    <Window x:Class="WpfComboBoxTest.Window6"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:local="clr-namespace:WpfComboBoxTest"

       xmlns:dat="clr-namespace:System.Windows.Data;assembly=PresentationFramework"

        Title="Window6" Height="300" Width="300">

        <Window.Resources>

            <local:PersonCollection x:Key="perserCollectionKey" />

            <local:AnimalCollection x:Key="animalCollectionKey" />

            <!--Person-->

            <DataTemplate DataType="{x:Type local:Person}">

                <Border>

                    <TextBlock Text="{Binding Name}"  />

                </Border>

            </DataTemplate>

            <!--Animal-->

            <DataTemplate DataType="{x:Type local:Animal}">

                <Border>

                    <TextBlock Text="{Binding Description}"  />

                </Border>

            </DataTemplate>

        </Window.Resources>

        <StackPanel>

            <ComboBox  Name="comboBox">

                <Grid>

                    <Grid.ColumnDefinitions>

                        <ColumnDefinition />

                        <ColumnDefinition />

                    </Grid.ColumnDefinitions>

                    <Grid.RowDefinitions>

                        <RowDefinition />

                        <RowDefinition />

                        <RowDefinition />

                        <RowDefinition />

                    </Grid.RowDefinitions>

                    <TextBlock Text="Person collection"  Grid.Row="0" Grid.Column="0" />

                    <TextBlock Text="Person collection"  Grid.Row="2" Grid.Column="0" />

                    <ListBox ItemsSource="{Binding Source={StaticResource perserCollectionKey}}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"  />

                    <ListBox ItemsSource="{Binding Source={StaticResource animalCollectionKey}}" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2"   />

                </Grid>

            </ComboBox>

        </StackPanel>

    </Window>

     

    In the code behind:
    using System.Windows;

    using System.Collections.ObjectModel;

    namespace WpfComboBoxTest

    {

        public partial class Window6 : Window

        {

            public Window6()

            {

                InitializeComponent();

            }

        }

        public class PersonCollection : ObservableCollection<Person>

        {

            public PersonCollection()

            {

                this.Add(new Person() { Name = "Person1", ID = "Person" });

                this.Add(new Person() { Name = "Person2", ID = "Person" });

            }

        }

        public class AnimalCollection : ObservableCollection<Animal>

        {

            public AnimalCollection()

            {

                this.Add(new Animal() { Description = "Animal1", ID = "Animal" });

                this.Add(new Animal() { Description = "Animal2", ID = "Animal" });

            }

        }

        public class Person

        {

            public string Name { get; set; }

            public string ID { get; set; }

        }

        public class Animal 

        {

            public string Description { get; set; }

            public string ID { get; set; }

        }

    }

     

    Hope this helps.

    Thanks.

     

    Tuesday, April 28, 2009 7:49 AM
  • I was able to put the two collections in one collection so my problem is solved, the items have a header. thanks for the help
    Wednesday, April 29, 2009 8:30 AM