SAG
SAG

Reputation: 113

Can I use a WrapPanel to organize ListView group headers?

I would like to be able to use a WrapPanel to wrap by group header instead of by item.

I have implemented the following ICollectionView view for a ListView bound to an ObservableCollection studentlist:

        view = CollectionViewSource.GetDefaultView(studentlist);
        view.GroupDescriptions.Add(new PropertyGroupDescription("sectionoutput"));
        view.SortDescriptions.Add(new SortDescription("sectionoutput", ListSortDirection.Ascending));
        view.SortDescriptions.Add(new SortDescription("displayname", ListSortDirection.Ascending));

The XAML includes a style resource to set the template for the group header:

    <Style x:Key="ContainerStyle" TargetType="{x:Type GroupItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                        <Expander Header="{Binding Name}" IsExpanded="{Binding Name, Mode=OneWay, Converter={StaticResource expanderconverter}}">
                            <ItemsPresenter />
                        </Expander>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

This Style is used as the GroupStyle for the ListView:

    <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled">            
        <ListView.GroupStyle>
            <GroupStyle ContainerStyle="{StaticResource ContainerStyle}"/>
        </ListView.GroupStyle>
...
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding displayname}">
                </TextBlock>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

As is, the code presents a vertical list of student names grouped by a header listing their section number. But I would like to list the groups sequentially in a horizontal direction.

I know that I am able to organize the items in the ListView with a WrapPanel:

        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Horizontal" ItemWidth="150">                        
                </WrapPanel>
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>

But this code merely displays the students in a group side by side rather than displaying the groups themselves side by side. What I would like to do is have the groups themselves wrapped horizontally. I've tried to implement a wrap panel in the style resource, but I haven't been successful and have been wondering if there is a way to wrap by group.

I figure it is possible to do this by switching to a TreeView and turning the groups into Items. But I would prefer to use a ListView if at all possible because my program implements a class that takes the ListView as an argument.

Upvotes: 1

Views: 119

Answers (2)

mm8
mm8

Reputation: 169200

The GroupStyle has a Panel property that you can set to an ItemsPanelTemplate with a WrapPanel:

<ListView.GroupStyle>
    <GroupStyle ContainerStyle="{StaticResource ContainerStyle}">
        <GroupStyle.Panel>
            <ItemsPanelTemplate>
                <WrapPanel />
            </ItemsPanelTemplate>
        </GroupStyle.Panel>
    </GroupStyle>
</ListView.GroupStyle>

Upvotes: 1

trix
trix

Reputation: 898

Suppose to have a ViewModel that is the DataContext of the XAML posted below that contains an ObservableCollection<GroupViewModel> named GroupsViewModel.

GroupViewModel merely has a property named GroupName that is the name of the Group to show and it has a property of ObservableCollection<StudentViewModel>.

StudentViewModel has the property displayName to display the name of the Student.

Said so, by using an Expander and 2 nested ListBox you can get what you asked, like the following code:

<ListBox ItemsSource="{Binding GroupsViewModel}">
<ListBox.ItemTemplate>
    <DataTemplate>
        <Grid>
            <Expander HorizontalAlignment="Left" IsExpanded="True" Header="{Binding GroupName}">
                <ListBox ItemsSource="{Binding StudentViewModel}" HorizontalAlignment="Left">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding displayname}" />
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <StackPanel Orientation="Vertical"></StackPanel>
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                </ListBox>
            </Expander>
        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

Upvotes: 0

Related Questions