简体   繁体   中英

How do I create collapsible group headers with child items in a ListBox?

I have a ListBox populated by grouped data with a header and child items beneath it - I want to customize the control such that each group header is an Expander (initially closed) and expanding it would reveal the items for that group underneath it

I'm still new to WPF so how would I do this? Do I need to implement data templates for the HeaderTemplate of the GroupStyle (would this contain an ItemsPresenter here?) and the ItemTemplate or would I need to create a completely new ControlTemplate in addition to the two data templates?

Also, would using an Expander for headers disable the item virtualization feature of the ListBox? If so what can I do to ensure this doesn't happen? If I put a VirtualizingStackPanel in the Expander content, would that mitigate this or is this unecessary?

My grouping is very simple and simply a flat collection on one field:

ICollectionView collegeView = new ListCollectionView(playerDatabase);
collegeView.GroupDescriptions.Add(new PropertyGroupDescription("CollegeName"));
collegeView.SortDescriptions.Add(new SortDescription("CollegeName", ListSortDirection.Ascending));
collegeView.SortDescriptions.Add(new SortDescription("FirstName", ListSortDirection.Ascending));
lstCollege.ItemsSource = collegeView;

UPDATE This is what I have tried so far:

<ListBox x:Name="lstCollege" IsSynchronizedWithCurrentItem="True">
<ListBox.GroupStyle>
    <GroupStyle>
        <GroupStyle.HeaderTemplate>
            <DataTemplate>
                <Border Background="Blue" CornerRadius="5">
                     <Expander Header="{Binding Path=Name}" FontWeight="Bold" Foreground="White" Padding="3">
                         <ItemsPresenter />
                     </Expander>
                </Border>
            </DataTemplate>
        </GroupStyle.HeaderTemplate>
    </GroupStyle>
</ListBox.GroupStyle>

<ListBox.ItemTemplate>
    <DataTemplate>
        <StackPanel Orientation="Vertical">
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0} {1}">
                        <Binding Path="FirstName" />
                        <Binding Path="LastName" />
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </StackPanel>
    </DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Unfortunately, what this renders is an Expander for each group, however the items are not rendered inside of it - they are rendered outside the group item and the Expander is empty

I think the reason this is happening is because a GroupItem is rendered separately from the ListItem (or whatever it's called) and therefore the ListViewItem is not contained inside each GroupItem ...I think the way the ListBox renders it is GroupItem, ListItem, ListItem, ListItem, GroupItem, ListItem etc.

How would I change the control so that each GroupItem can also contain a set of ListItems ?

You should be able to create a GroupStyle and specifically use the ContainerStyle to define groups that are collapsible using an Expander. This doesn't require a DataTemplate or a ControlTemplate as it is specific to the grouping functionality. Take a look at the ' GroupStyle.ContainerStyle ' property on MSDN, and this other answer also provides an example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM