我在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列进行排序/分组工作正常
然后对非可分组列进行排序/分组会使先前的分组保持原位。
答案 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;属性是关于。