在 ObjectListView 控件的演示中有此代码(在“复杂示例”选项卡页面中)允许自定义编辑器(组合框)(适应我的情况并为清晰起见进行了编辑):
EventHandler CurrentEH;
private void ObjectListView_CellEditStarting(object sender,
CellEditEventArgs e)
{
if (e.Column == SomeCol)
{
ISomeInterface M = (e.RowObject as ObjectListView1Row).SomeObject; //(1)
ComboBox cb = new ComboBox();
cb.Bounds = e.CellBounds;
cb.DropDownStyle = ComboBoxStyle.DropDownList;
cb.DataSource = ISomeOtherObjectCollection;
cb.DisplayMember = "propertyName";
cb.DataBindings.Add("SelectedItem",
M, "ISomeOtherObject", false,
DataSourceUpdateMode.Never);
e.Control = cb;
cb.SelectedIndexChanged +=
CurrentEH = (object sender2, EventArgs e2) =>
M.ISomeOtherObject =
(ISomeOtherObject)((ComboBox)sender2).SelectedValue; //(2)
}
}
private void ObjectListView_CellEditFinishing(object sender,
CellEditEventArgs e)
{
if (e.Column == SomeCol)
{
// Stop listening for change events
((ComboBox)e.Control).SelectedIndexChanged -= CurrentEH;
// Any updating will have been down in the SelectedIndexChanged
// event handler.
// Here we simply make the list redraw the involved ListViewItem
((ObjectListView)sender).RefreshItem(e.ListViewItem);
// We have updated the model object, so we cancel the auto update
e.Cancel = true;
}
}
我在 objectlistviews 中有太多其他带有组合编辑器的列,无法使用复制和粘贴策略(此外,复制和粘贴是严重的错误来源),因此我尝试对代码进行参数化以将代码重复降至最低。ObjectListView_CellEditFinishing 是小菜一碟:
HashSet<OLVColumn> cbColumns = new HashSet<OLVColumn> (new OLVColumn[] { SomeCol, SomeCol2, ...};
private void ObjectListView_CellEditFinishing(object sender,
CellEditEventArgs e)
{
if (cbColumns.Contains(e.Column)) ...
但 ObjectListView_CellEditStarting 是有问题的。
我想在 CellEditStarting 中我将不得不分别区分每种情况:
private void ObjectListView_CellEditStarting(object sender,
CellEditEventArgs e)
{
if (e.Column == SomeCol)
// code to create the combo, put the correct list as the datasource, etc.
else if (e.Column == SomeOtherCol)
// code to create the combo, put the correct list as the datasource, etc.
等等。
但是如何参数化“创建组合的代码,将正确的列表作为数据源等”?问题线是
(1) 获取一些对象。属性名称各不相同。
(2) 设置ISomeOtherObject,属性名也不同。
类型也各不相同,但我可以使用通用方法结合不太“类型安全”的 API 来涵盖这些情况(例如,cb.DataBindings.Add 和 cb.DataSource 都使用object
)
反射?更多的lambda?有任何想法吗?还有其他方法可以做到这一点吗?
PS:我希望能够做这样的事情:
private void ObjectListView_CellEditStarting(object sender,
CellEditEventArgs e)
{
if (e.Column == SomeCol)
SetUpCombo<ISomeInterface>(ISomeOtherObjectCollection,
"propertyName",
SomeObject,
ISomeOtherObject);
else if (e.Column == SomeOtherCol)
SetUpCombo<ISomeInterface2>(ISomeOtherObject2Collection,
"propertyName2",
SomeObject2
ISomeOtherObject2);
等等。或类似的东西。
我知道,参数 SomeObject 和 ISomeOtherObject 不是真正的参数,但你明白我想要什么。我不想一次又一次地重复相同的代码框架。
一种解决方案是像 C 的 DEFINE 这样的“预处理器泛型”,但我不认为 c# 有这样的东西。
那么,有没有人有一些替代的想法来解决这个问题?