如何在ObjectListView中对对象进行分组和排序?

时间:2019-06-24 22:53:26

标签: c# winforms sorting grouping objectlistview

我正在尝试将ObjectListView中的对象列表分组。

ObjectListView应该根据第一列对对象进行分组,然后根据自定义排序对同一列进行排序。

我该怎么做?我已经阅读了ObjectListView的文档: http://objectlistview.sourceforge.net/cs/gettingStarted.html#gettingstarted

到目前为止,我已经实现了自定义排序,但是不确定如何触发分组?请记住,我试图对第一列进行分组,然后再应用自定义排序。

我的自定义排序与BeforeSorting事件有关:

// after initializing components
olv.BeforeSorting += olv_BeforeSorting;

然后...

private void olv_BeforeSorting(object sender,BrightIdeasSoftware.BeforeSortingEventArgs e)
{
        olvDataSource.Sort((x, y) => x.Group.ID.CompareTo(y.Group.ID));
        e.Handled = true;
}

ObjectListView显示我的有序对象列表,但没有组合在一起。每个对象都显示在自己的行上,没有组标题。

如何对我的对象进行分类?

3 个答案:

答案 0 :(得分:1)

您可以按以下方式强制分组列:

olv.ShowGroups = true;
olv.AlwaysGroupByColumn = olvColumn1;

如果您想在列中显示一个值,并按不同的值分组,则可以使用GroupByKeyGetter

olvColumn1.GroupKeyGetter = GroupKeyGetter;

代理将类似于:

private object GroupKeyGetter(object rowObject)
{
    var o = rowObject as MyClass;

    if(o == null)
        return "unknown";

    return o.ID;
}

有些东西只有在您打电话之前才会生效

olv.RebuildColumns();

始终按(任意函数)排序

如果要对某些自定义逻辑强制排序,则可以在ListViewItemSorter事件中使用BeforeSorting。这类似于注册CustomSorter(但在ShowGroups为true时似乎不起作用)。

olv.BeforeSorting += olv_BeforeSorting;

然后

private void olv_BeforeSorting(object sender, BrightIdeasSoftware.BeforeSortingEventArgs e)
{
    //example sort based on the last letter of the object name
    var s = new OLVColumn();
    s.AspectGetter = (o) => ((MyClass)o).Name.Reverse().First(); 

    this.olv.ListViewItemSorter = new ColumnComparer(
                s, SortOrder.Descending, e.ColumnToSort, e.SortOrder);
    e.Handled = true;
}

答案 1 :(得分:1)

我正在与可能遇到这里的任何人分享此信息,以寻求一种在ObjectListView内的组上应用自定义排序的方法。

也许有更好的方法可以这样做,但是这种方法对我有用。

colFirst.GroupFormatter = (BrightIdeasSoftware.OLVGroup group, BrightIdeasSoftware.GroupingParameters parms) =>
{
    ObjectA a = (OjectA)group.Key;

    /* Add any processing code that you need */

    group.Task = " . . . ";
    group.Header = "Special Name: " + a.Name;
    group.Subtitle = $("Object A: {a.Index}, Total Water Consumption: {a.WaterConsumption}");

    // This is what is going to be used as a comparable in the GroupComparer below
    group.Id = a.ID;

    // This will create the iComparer that is needed to create the custom sorting of the groups
    parms.GroupComparer = Comparer<BrightIdeasSoftware.OLVGroup>.Create((x, y) => (x.GroupId.CompareTo(y.GroupId)));
};

OLVColumn.GroupFormatter的解释如下: http://objectlistview.sourceforge.net/cs/recipes.html#how-do-i-put-an-image-next-to-a-group-heading

答案 2 :(得分:0)

这很有效,基本上是这里的食谱中描述的http://objectlistview.sourceforge.net/cs/recipes.html?highlight=sort#how-can-i-change-the-ordering-of-groups-or-rows-within-a-group

首先订阅 olv BeforeCreatingGroups 事件。

然后在事件处理程序中创建自定义排序比较器。在这种情况下,对于匹配“Turtles”的组,它将推到排序的末尾,但显然您可以在其中添加任何您想要的复杂逻辑。

private void Olv_BeforeCreatingGroups(object sender, CreateGroupsEventArgs e)
{
    e.Parameters.GroupComparer = Comparer<BrightIdeasSoftware.OLVGroup>.Create(
        (x, y) => (
            x.Header == "Turtles" ? 1
                : x.GroupId.CompareTo(y.GroupId)
        )
    );
}

这是我最初使用的,因为它是食谱中的内容。但我最终转向了更像 Marwan 的答案,因为它创造了一个空间来重新配置组标题本身。