我在FastObjectListView(2.9.1)中错误地使用ShowGroups还是错误?

时间:2017-11-18 07:09:01

标签: c# winforms objectlistview

我在v2.9.1中遇到过FastObjectListView的问题。

作为一个最小的测试示例:我有一个FastObjectListView,我以编程方式添加两个OLVColumn对象。当第一列不是Groupable时,我打开ShowGroups,我在FastListGroupingStrategy.GetGroup中获得Null Ref Exception。

这是因为indexToGroupMap永远不会在FastListGroupingStrategy.GetGroups中实例化,因为ObjectListView.BuildGroups中的一个检查会跳过非Groupable列的Group构建。根据此代码片段:

 if (parms.GroupByColumn != null)
     args.Canceled = !parms.GroupByColumn.Groupable;
 this.OnBeforeCreatingGroups(args);
 if (args.Canceled)
    return;

所以问题是,我是否滥用了控件?我应该根据当前列是否可排序来打开和关闭ShowGroups吗?

或者它是一个错误? (如果this.OLVGroups == null,可以通过更改VirtualObjectListView.GetDisplayOrderOfItemIndex来返回itemIndex来修复可能?)

示例代码

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        InitColumns();
        fastObjectListView1.ShowGroups = true;
        modelObjects_.Add(new ModelObject { Name = "Anne", Age = 20 });
        modelObjects_.Add(new ModelObject { Name = "Beth", Age = 20 });
        modelObjects_.Add(new ModelObject { Name = "Claire", Age = 32 });
        modelObjects_.Add(new ModelObject { Name = "Della", Age = 31 });
        modelObjects_.Add(new ModelObject { Name = "Ellie", Age = 20 });
        modelObjects_.Add(new ModelObject { Name = "Fiona", Age = 31 });
        fastObjectListView1.Objects = modelObjects_;
    }


    void InitColumns()
    {
        {
            OLVColumn col = new OLVColumn();
            col.Name = "NameColumn";
            col.IsVisible = true;
            col.AspectGetter = o => CastToModel(o).Name;
            col.AspectToStringConverter = a => a.ToString();
            col.Groupable = false;
            col.IsEditable = false;
            col.Text = "Name";
            col.Width = 150;
            fastObjectListView1.AllColumns.Add(col);
        }
        {
            OLVColumn col = new OLVColumn();
            col.Name = "AgeColumn";
            col.IsVisible = true;
            col.AspectGetter = o => CastToModel(o).Age;
            col.AspectToStringConverter = a => a.ToString();
            col.Groupable = true;
            //col.ImageGetter = 
            col.IsEditable = false;
            col.Text = "Age";
            col.Width = 50;
            fastObjectListView1.AllColumns.Add(col);
        }
        fastObjectListView1.RebuildColumns();
    }

    ModelObject CastToModel(object o)
    {
        return (ModelObject)o;
    }  

List<ModelObject> modelObjects_ = new List<ModelObject>();
}

public class ModelObject
{
    public string Name;
    public int Age;
}

还有另外一种副作用(我意外):

通过单击列标题对Groupable列进行排序/分组工作正常

然后对非可分组列进行排序/分组会使先前的分组保持原位。

1 个答案:

答案 0 :(得分:1)

使用col.Groupable = true;告诉ListView&#34;是否可以按列进行分组&#34;。

但是第一列是一个特殊的列,其中一个原因是因为它至少在最初用于组。这意味着您需要通过设置以下内容来扩大范围;

col.Name = "AgeColumn";
...
fastObjectListView1.AlwaysGroupByColumn = col;

然而,这导致您无法通过任何其他列进行分组。在您的示例中不是问题,但如果您扩展模型,则可能会出现问题。

另一种解决方案是使用GroupKeyGetter代替。

在这里,您需要定义您的第一列有点不同,并仅为此列设置GroupKeyGetter。

//Define your first column at the class level;
private OLVColumn colName;

//Define InitColumns
void InitColumns()
{
    colName = new OLVColumn();
    colName.Name = "NameColumn";
    colName.Groupable = true;  //Make this groupable again, as we effectively override it.
    ...
    //Rest same as before
}

//In form_load
private void Form1_Load(object sender, EventArgs e)
{
    InitColumns();            
    ...
    //define your objects, same as before

    this.colName.GroupKeyGetter = delegate (object rowObject)
    {
        ModelObject item = (ModelObject)rowObject;
        return item.Age;
    };

    fastObjectListView1.ShowGroups = true;
    fastObjectListView1.Objects = modelObjects_;
}

这有一个优点,它&#34;覆盖&#34;第一列的分组方式(有效地使用与第二列相同的方式),但仍然允许您按所有其他列进行分组而没有任何问题。

  

还有另外一种副作用(我意外):

     

通过单击列标题对Groupable列进行排序/分组   工作正常

     

然后对非Groupable列进行排序/分组就会离开   分组到位。

这是预期的行为。这就是&#34; Groupable&#34;属性是关于。