我在 FastObjectListView (2.9.1) 中错误地使用了 ShowGroups 还是错误?
Am I incorrectly using ShowGroups in FastObjectListView (2.9.1) or is it a bug?
我在 v2.9.1 中遇到了 FastObjectListView 的问题。
作为一个最小的测试示例:我有一个 FastObjectListView,我以编程方式向其添加了两个 OLVColumn objects。当第一列不可分组并且我打开 ShowGroups 时,我在 FastListGroupingStrategy.GetGroup.
中得到一个 Null Ref 异常
这是因为 indexToGroupMap 从未在 FastListGroupingStrategy.GetGroup 中实例化,因为 ObjectListView.BuildGroups 中的检查跳过了 non-Groupable 列的组构建。根据此代码片段:
if (parms.GroupByColumn != null)
args.Canceled = !parms.GroupByColumn.Groupable;
this.OnBeforeCreatingGroups(args);
if (args.Canceled)
return;
那么问题来了,我是不是在滥用控件?是否应该由我根据当前列是否可排序来打开和关闭 ShowGroups?
还是bug? (如果 this.OLVGroups == null, 可能 通过将 VirtualObjectListView.GetDisplayOrderOfItemIndex 更改为 return 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;
}
还有一个副作用(出乎我意料):
Sorting/grouping 通过单击列 header 在可分组列上工作正常
然后 sorting/grouping 在 non-Groupable 列上保留先前的分组。
使用 col.Groupable = true;
告诉 ListView“是否可以按列分组”。
但是第一列是一个特殊的列,其中一个原因是因为它用于组,至少最初是这样。这意味着您需要通过设置以下内容来覆盖它;
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_;
}
这样做的好处是它“覆盖”了第一列的分组方式(有效地使用与第二列相同的方式),但仍然允许您毫无问题地按所有其他列分组。
There is another side effects (unexpected by me):
Sorting/grouping on a Groupable column via clicking column header
works ok
Then sorting/grouping on a non-Groupable column leaves previous
grouping in place.
这是预期的行为。这就是“Groupable”属性的意义所在。
我在 v2.9.1 中遇到了 FastObjectListView 的问题。
作为一个最小的测试示例:我有一个 FastObjectListView,我以编程方式向其添加了两个 OLVColumn objects。当第一列不可分组并且我打开 ShowGroups 时,我在 FastListGroupingStrategy.GetGroup.
中得到一个 Null Ref 异常这是因为 indexToGroupMap 从未在 FastListGroupingStrategy.GetGroup 中实例化,因为 ObjectListView.BuildGroups 中的检查跳过了 non-Groupable 列的组构建。根据此代码片段:
if (parms.GroupByColumn != null)
args.Canceled = !parms.GroupByColumn.Groupable;
this.OnBeforeCreatingGroups(args);
if (args.Canceled)
return;
那么问题来了,我是不是在滥用控件?是否应该由我根据当前列是否可排序来打开和关闭 ShowGroups?
还是bug? (如果 this.OLVGroups == null, 可能 通过将 VirtualObjectListView.GetDisplayOrderOfItemIndex 更改为 return 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;
}
还有一个副作用(出乎我意料):
Sorting/grouping 通过单击列 header 在可分组列上工作正常
然后 sorting/grouping 在 non-Groupable 列上保留先前的分组。
使用 col.Groupable = true;
告诉 ListView“是否可以按列分组”。
但是第一列是一个特殊的列,其中一个原因是因为它用于组,至少最初是这样。这意味着您需要通过设置以下内容来覆盖它;
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_;
}
这样做的好处是它“覆盖”了第一列的分组方式(有效地使用与第二列相同的方式),但仍然允许您毫无问题地按所有其他列分组。
There is another side effects (unexpected by me):
Sorting/grouping on a Groupable column via clicking column header works ok
Then sorting/grouping on a non-Groupable column leaves previous grouping in place.
这是预期的行为。这就是“Groupable”属性的意义所在。