【问题标题】:WPF - Using CollectionViewSource with ALREADY grouped dataWPF - 将 CollectionViewSource 与已经分组的数据一起使用
【发布时间】:2016-12-12 07:55:25
【问题描述】:

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

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

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

然而,WPF 似乎希望将未分组的列表馈送到其 CVS,以便它可以自己对所有内容进行分组。如何告诉 WPF CVS VM 已包含分组数据?

【问题讨论】:

    标签: c# wpf wpf-controls collectionviewsource


    【解决方案1】:

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

    你基本上有两个选择。

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

    2. 将 Source 设置为分组集合并为 Grouping 对象定义一个 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>
    

    【讨论】:

    • 我很高兴假设源已分组并设置模板以适应它。我将在 ListView 而不是 ListBox 中显示,如果我希望 Sections 总是展开,如果不是空的,你能建议一个不是 Expander 的容器吗?
    • 扩展器有什么问题?您可以将其 IsExpanded 设置为 true 以使其默认展开。如果您不想展开/折叠组,您可以移除展开器并使用 ListBox 或 ItemsControl 作为 DataTemplate 的根面板。
    • 我正在尝试模仿我在 Win8 中成功使用的 GroupStyle HidesIfEmpty="True"。正如你所建议的,我将用其他东西替换扩展器。谢谢
    • 我可以通过选项 2 完成所有操作,但是对于大型数据集来说速度非常慢。我想知道这样做是否会导致我失去虚拟化。我在猜测,但看起来分组集中每一行的“名称”属性正在被读取,而不仅仅是那些需要绘制当前视图的属性
    • 阅读此问题后,stackoverflow.com/questions/12569506/listbox-not-virtualizing 我可以看到内部 ListBox\ListView 需要设置 MaxHeight 以便您仍然可以获得虚拟化。您应该在回答中注意到这一点
    猜你喜欢
    • 1970-01-01
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多