如何在WPF ListView中对项目进行分组

23

我有一个 ListView,想要将结果分组,但是我找到的例子都不起作用。如何进行分组?

我想根据自定义对象的 Status 属性进行分组。

这是我目前的代码:

<ListView IsSynchronizedWithCurrentItem="True"
          ItemsSource="{Binding}"
          HorizontalContentAlignment="Stretch"
          ScrollViewer.HorizontalScrollBarVisibility="Disabled"
          Background="Transparent" SelectionChanged="ListView_SelectionChanged"
          Name="lstShelvedOrders">

        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock FontWeight="Bold" FontSize="15"
                         Text="{Binding Path=Status}"/>
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>

        <ListView.ItemContainerStyle>
            <Style TargetType="{x:Type ListViewItem}">
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="Width" Value="Auto" />
                <Setter Property="FontSize" Value="10.4"  />               
            </Style>
        </ListView.ItemContainerStyle>

        <ListView.View>
            <GridView>
                <GridViewColumn DisplayMemberBinding="{Binding Path=Number}" Header="Shelve ID"  />
                <GridViewColumn DisplayMemberBinding="{Binding Path=Customer}" Header="Customer" />
                <GridViewColumn DisplayMemberBinding="{Binding Path=PurchaseOrderNo}" Header="PO Number" />
                <GridViewColumn DisplayMemberBinding="{Binding Path=SubmittedBy}" Header="Shelved By"  />
                <GridViewColumn DisplayMemberBinding="{Binding Path=OrderDate, StringFormat=MMM dd\, yyyy}" Header="Date"  />
                <GridViewColumn DisplayMemberBinding="{Binding Path=CustomerTerms.Description}" Header="Order Terms"  />
                <GridViewColumn DisplayMemberBinding="{Binding Path=ShippingMethod.Description}" Header="Shipping"  />
                <GridViewColumn DisplayMemberBinding="{Binding Path=TotalPrice, StringFormat=c}" Header="Order Total"  />
            </GridView>
        </ListView.View>
    </ListView>

以下是我的代码:

 void ShelvedOrderList_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
 {
     AddGrouping();
 }

 private void AddGrouping()
 {
     if ( lstShelvedOrders.ItemsSource == null)
     {
         return;
     }

     CollectionView myView = (CollectionView)CollectionViewSource.GetDefaultView(lstShelvedOrders.ItemsSource);
     PropertyGroupDescription groupDescription = new PropertyGroupDescription("Status");
     myView.GroupDescriptions.Add(groupDescription);
 }
2个回答

24

我立刻注意到了一件事 - GroupStyle.HeaderTemplate会应用于一个CollectionViewGroup,因此你的DataTemplate应该如下所示:

<GroupStyle>
    <GroupStyle.HeaderTemplate>
        <DataTemplate>
            <TextBlock FontSize="15" FontWeight="Bold" Text="{Binding Name}"/>
        </DataTemplate>
    </GroupStyle.HeaderTemplate>
</GroupStyle>

CollectionViewGroup.Name将被分配该组的Status值。


现在我得到了三个组实例,但是它们已经分组了,这是一个胜利。你正在成为我的私人英雄。 - Russ
我该如何在MVVM环境中使用这段代码?没有设置列表项的附近代码行。它们是通过绑定使用的。我找不到可以将AddGrouping()方法挂钩的事件。当整个用户控件的DataContext更改时,列表的ItemsSource仍然为null。我猜需要等待一段时间。 - ygoe
您可以在XAML中创建一个带有适当分组的CollectionViewSource,并将您的控件绑定到它,而不是直接绑定源集合。 - Robert Macnee
有没有办法做到这一点,并使标题成为可选择的ListView项目?我有一个类似的问题,但是当我按下按钮时,我需要根据所选内容删除/编辑,即整个组或者只能删除该组中的子项。 - JTester

3
我认为这样做可以更好,使用一个带有新 ControlTemplate 的 GroupStyle:
<ListView ItemsSource="{Binding Path=ContactsView}">
  <ListView.GroupStyle>
    <GroupStyle>
      <GroupStyle.ContainerStyle>
        <Style TargetType="{x:Type GroupItem}">
          <Setter Property="Template" Value="{StaticResource ContactsGroupItemTemplate}" />
        </Style>
      </GroupStyle.ContainerStyle>
    </GroupStyle>
  </ListView.GroupStyle>

...

<ControlTemplate TargetType="{x:Type GroupItem}" x:Key="ContactsGroupItemTemplate">
  <Expander IsExpanded="False">
    <Expander.Header>
      <DockPanel>
        <TextBlock FontWeight="Bold" Text="{Binding Path=Name}" Margin="5,0,0,0" Width="100"/>
          <TextBlock FontWeight="Bold" Text="{Binding Path=ItemCount}"/>
          <TextBlock FontWeight="Bold" Text=" Items"/>
      </DockPanel>
    </Expander.Header>
    <Expander.Content>
      <ItemsPresenter />
    </Expander.Content>
  </Expander>
</ControlTemplate>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接