WPF: Bind Collection with Collection to a ListBox with groups

前端 未结 2 828
轮回少年
轮回少年 2021-02-04 16:37

sometimes WPF is too complex for me. I\'ve got my \"Window1\" holding a collection of \"Group\"s. \"Group\" is a class with a collection of \"Person\"s. In the end this should b

相关标签:
2条回答
  • 2021-02-04 17:06

    If you have a copy of Programming WPF, jump to Page 221. If not I'll summarize (in my inept sort of way)

    First you don't need to manually group the Person objects.

    If each Person object has a Group property,

    People people = // retrieve the List<Person> somehow
    ICollectionView view = CollectionViewSource.GetDefaultView(people);
    view.GroupDescriptions.Add( new PropertyGroupDescription("Group") );
    

    All controls that derive from ItemsControl can display grouped items, so

    // the XAML
    <ListBox ... ItemsSource={Binding}>
      <ListBox.GroupStyle>
        <x:Static Member="GroupStyle.Default" />
      </ListBox.GroupStyle>
    </ListBox>
    

    You can also define a custom GroupStyle and specify the GroupStyle.HeaderTemplate to define a new DataTemplate that shows custom attributes like 'some PropertyValue (Count)' - Bind the one TextBlock to {Binding SomeProperty} and the other to {Binding ItemCount}

    HTH

    0 讨论(0)
  • 2021-02-04 17:07

    Well, I am not sure if this is what you want achieve but here is a way that you can try:

    Assuming your classes are like these:

    public class Group
    {
        public string Name { get; set; }
        public List<Contact> Contacts { get; set; }
    }
    
    public class Contact
    {
        public string Name { get; set; }
        public bool IsOnline { get; set; }
    }
    

    You can set ListBox.ItemTemplate as another ListBox bind to Contacts property, like:

    <CollectionViewSource x:Key="groups" Source="{Binding}" >
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="Name" />
        </CollectionViewSource.GroupDescriptions>
    </CollectionViewSource>
    
    <DataTemplate x:Key="groupTemplate" DataType="Group">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Name}" />
        </StackPanel>
    </DataTemplate>
    
    <ListBox ItemsSource="{Binding Source={StaticResource groups}}">
        <ListBox.GroupStyle>
            <GroupStyle HeaderTemplate="{StaticResource groupTemplate}" />
        </ListBox.GroupStyle>
        <ListBox.ItemTemplate>
            <DataTemplate DataType="Contact">
                <ListBox ItemsSource="{Binding Contacts}">
                    <ListBox.ItemTemplate>
                        <DataTemplate DataType="Contact">
                            <TextBlock Text="{Binding Name}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    You have to style the inner listbox a little bit.

    Edit: Another solution by using TreeView

    <DataTemplate DataType="Contact">
       <TextBlock Text="{Binding Name}" />
    </DataTemplate>
    
    <TreeView ItemsSource="{Binding Source={StaticResource groups}}">
        <TreeView.ItemTemplate>
            <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding Contacts}">
                <TextBlock Text="{Binding Name}" />
            </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
    </TreeView>
    
    0 讨论(0)
提交回复
热议问题