WPF - 将 CollectionViewSource 与 ALREADY 分组数据一起使用

WPF - Using CollectionViewSource with ALREADY grouped data

我有一个在 Windows 8、Android 和 iOS 中使用的 ViewModel 作为 Xamarin 项目的一部分。我现在需要在 WPF 的 ListView 中显示该虚拟机。

该 VM 将一些 已经 分组的数据公开为 ObservableCollection<GroupedResult<string, SearchResult>>。 GroupResult 有一个 Key (String) 属性 和一个 IEnumerable Source 属性

使用 Windows 8 ListView,我可以将该数据分配给 CollectionViewSource (CVS),告诉 CVS 项目的路径 属性 PropertyPath("Source"),它工作正常。

但是 WPF 似乎想要将未分组的列表提供给它的 CVS,以便它可以自己对它进行分组。我如何告诉 WPF CVS VM 包含已经分组的数据?

恐怕 WPF 中的 System.Windows.Data.CollectionViewSource class 没有 IsSourceGrouped 或等效项 属性,因此您不能真正告诉它数据已经分组。

你基本上有两个选择。

  1. 取消分组源集合并将 CollectionViewSource 的 Source 属性 设置为未分组的集合,并像往常一样将 PropertyGroupDescription 添加到其 GroupDescriptions 集合:https://msdn.microsoft.com/en-us/library/ms742542(v=vs.110).aspx

  2. 将源设置为分组集合并为分组对象定义一个 ItemTemplate:

    public MainWindow()
    {
        InitializeComponent();
        List<User> items = new List<User>();
        items.Add(new User() { Name = "John Doe", Age = 42, Sex = SexType.Male });
        items.Add(new User() { Name = "Jane Doe", Age = 39, Sex = SexType.Female });
        items.Add(new User() { Name = "Sammy Doe", Age = 13, Sex = SexType.Male });
    
        var result =
            from x in items
            group x by x.Sex into g
            orderby g.Key
            select g;
    
        listBox.ItemsSource = result;
    }
    

   <ListBox x:Name="listBox">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Expander Header="{Binding Key}">
                    <ListBox ItemsSource="{Binding}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <TextBlock Text="{Binding Name}"/>
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </Expander>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>