ListView 按列值分组

Posted

技术标签:

【中文标题】ListView 按列值分组【英文标题】:ListView Grouping by Column Value 【发布时间】:2020-09-11 20:22:08 【问题描述】:

这样的ListView

Name    |    IP        |  Port
--------------------------------
Alice   | 192.168.0.1  |  1000
Bob     | 192.168.0.1  |  1000
Carol   | 192.168.0.1  |  1000
Dave    | 192.168.0.2  |  2000
Eve     | 192.168.0.2  |  2000

我想按 IP 分组,例如 Alice, Bob, Carol 和 Dave, Eve

如果是System.Collections.Generic.List,我使用FindAll

但是是ListViewItemCollection,我怎么分组?

我能想到的办法是用ListViewItemCollection通过for循环创建一个新的List。

还有其他方法吗?

【问题讨论】:

可以先将数据分组,再绑定到列表视图或其他控件 尝试以下操作:listView1.Controls.Cast().GroupBy(x => x.SubItems[1]) 【参考方案1】:

将ListViewItem 对象分组到ListView 控件中:

    将给定ColumnHeader 的SubItems 分组。 为每个组密钥创建一个新的ListViewGroup,并且, 将其分配给分组的ListViewItem 对象的Group 属性。

创建一个分组方法来应用它:

private void GroupListViewItems(int columnIndex)

    if (!listView1.Columns.Cast<ColumnHeader>()
        .Select(c => c.Index).Contains(columnIndex))
        return;

    listView1.BeginUpdate();
    listView1.Groups.Clear();

    var groups = listView1.Items.Cast<ListViewItem>()
        .GroupBy(x => x.SubItems[columnIndex].Text);

    foreach(var group in groups.OrderBy(x => x.Key))
    
        var g = new ListViewGroup(group.Key);

        listView1.Groups.Add(g);
        group.ToList().ForEach(x => x.Group = g);
    

    listView1.Columns.Cast<ColumnHeader>().ToList().ForEach(x => x.Width = -2);
    listView1.EndUpdate();

...也许是通过名称传递列的重载:

private void GroupListViewItems(string columnName)

    var columnHeader = listView1.Columns.Cast<ColumnHeader>()
        .FirstOrDefault(x => x.Text.ToLower().Equals(columnName.ToLower()));

    if (columnHeader != null)
        GroupListViewItems(columnHeader.Index);

...调用该方法并传递ColumnHeader 的名称/索引。要取消组合项目,只需清除ListView.Groups 属性即可。

【讨论】:

以上是关于ListView 按列值分组的主要内容,如果未能解决你的问题,请参考以下文章

按列值分组的列值更新mysql排名

如何按列值的计数进行分组并对其进行排序?

如何在 Pandas 数据框中按列值分组

按列值的前导字符对数据行进行分组

如何按列值分组应该只出现在第一行

按列值查询某些行的联合和分组