使用多个 collections 和自定义 headers 的 ListView 分组

ListView grouping using multiple collections and custom headers

我有三个 collections 像这样:

IReadOnlyList<Info> ListA = {'1A', '1B'}
IReadOnlyList<Info> ListB = {'2A', '2B'}
IReadOnlyList<Info> ListC = {'3A', '3B'}

我正在尝试将它们分组,为每个添加自定义 header,然后在 ListView 中显示。我试过这样做:

<ListView ItemsSource="{DynamicResource FullCollection}">
          <ListView.Resources>
            <CollectionViewSource x:Key="CollectionA" Source="{Binding CollectionA}" />
            <CollectionViewSource x:Key="CollectionB" Source="{Binding CollectionB}" />
            <CollectionViewSource x:Key="CollectionC" Source="{Binding CollectionC}" />
            <CompositeCollection x:Key="FullCollection">
              <ListViewItem IsEnabled="False">Header_A</ListViewItem>
              <CollectionContainer Collection="{Binding Source={StaticResource CollectionA}}" />
              <ListViewItem IsEnabled="False">Header_B</ListViewItem>
              <CollectionContainer Collection="{Binding Source={StaticResource CollectionB}}" />
              <ListViewItem IsEnabled="False">Header_C</ListViewItem>
              <CollectionContainer Collection="{Binding Source={StaticResource CollectionC}}" />
            </CompositeCollection>
          </ListView.Resources>
</ListView>
...

Then i created three seperate ICollectionView objects in viewmodel (CollectionA, CollectionB, CollectionC from ListA, ListB, ListC recpectively) like so:

 ICollectionView _collectionA= null;
 public ICollectionView CollectionA  //from ListA
    {
      get
      {
        if (_collectionA== null)
        {
          _collectionA = CollectionViewSource.GetDefaultView(ListA);  //original list
          PropertyGroupDescription groupDescription = new PropertyGroupDescription("Header_A");
          _collectionA.GroupDescriptions.Add(groupDescription);
        }
        return _collectionA;
      }
    }
...

不知何故我无法得到我想要的东西,我在这里做错了什么!?

我如何将它们与自定义 headers(和扩展器)分组,然后在我的 ListView 中显示,如下所示:

  ^ Header_A
       --1A
       --1B
   ^ Header_B
       --2A
       --2B
   ^ Header_C
       --3A
       --3B

您应该为组 header:

创建一个带有附加 属性 的视图模型
public class InfoViewModel
{
    public string Category { get; set; }
    public string Name { get; set; }
}

然后您可以将当前的 Info objects 翻译成 InfoViewModels 并按新的 属性 分组,例如:

var fullSourceCollection = ListA.Select(x => new InfoViewModel() { Category = "Header_A", Name = x.Name })
    .Merge(ListB.Select(x => new InfoViewModel() { Category = "Header_B", Name = x.Name })
    .Merge(ListC.Select(x => new InfoViewModel() { Category = "Header_C", Name = x.Name })
    .ToArray();
...
PropertyGroupDescription groupDescription = new PropertyGroupDescription(nameof(InfoViewModel.Category));
...

最后,您应该在视图中定义组样式:

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