在ObjectListView控件的演示中,有以下代码(在"Complex Example“选项卡页中),以允许自定义编辑器( ComboBox) (根据我的情况进行修改,为清楚起见进行了编辑):
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中有太多带有组合编辑器的其他列,不能使用复制粘贴策略(此外,复制粘贴是一个严重的bug来源),所以我尝试对代码进行参数化,以将代码复制保持在最低限度。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)获取SomeObject。属性名称会有所不同。
(2)设置ISomeOtherObject,属性名称也不一样。
类型也各不相同,但我可以用一个泛型方法结合一个不是很“类型安全”的API来处理这些情况(例如,cb.DataBindings.Add和cb.DataSource都使用object)。
倒影?更多的lambdas?有什么想法吗?有没有其他方法可以做到这一点呢?
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不是每个see的真实参数,但是您知道我想要什么了。我不想一遍又一遍地重复相同的代码框架。
一种解决方案是像C的定义这样的“预处理器泛型”,但我不认为c#有这样的东西。
那么,有没有人有其他的想法来解决这个问题呢?
发布于 2012-11-08 00:58:24
找到了。向Tejs致敬!
private void SetUpCombo(CellEditEventArgs e,
object ComboItems, string DisplayMember,
object DataSource, string PropertyName,
EventHandler evt)
{
ComboBox cb = new ComboBox();
cb.Bounds = e.CellBounds;
cb.DropDownStyle = ComboBoxStyle.DropDownList;
cb.DataSource = ComboItems;
cb.DisplayMember = DisplayMember;
cb.DataBindings.Add("SelectedItem", DataSource, PropertyName,
false, DataSourceUpdateMode.Never);
e.Control = cb;
cb.SelectedIndexChanged += CurrentEH = evt;
}和重写的CellEditStarting:
private void ObjectListView_CellEditStarting(object sender,
CellEditEventArgs e)
{
if (e.Column == SomeCol)
{
ISomeInterface M = (e.RowObject as ObjectListView1Row).SomeObject;
SetUpCombo(e,
ISomeOtherObjectCollection,"propertyName",
M, "ISomeOtherObject",
(sender2, e2) =>
M.ISomeOtherObject =
(ISomeOtherObject)((ComboBox)sender2).SelectedValue);
}
else if (e.Column == SomeOtherCol)
{
ISomeInterface2 M = (e.RowObject as ObjectListView1Row).SomeObject2;
SetUpCombo(e,
ISomeOtherObjectCollection2,"propertyName2",
M, "ISomeOtherObject2",
(sender2, e2) =>
M.ISomeOtherObject2 =
(ISomeOtherObject)((ComboBox)sender2).SelectedValue);
}以此类推。有些东西我还不喜欢。例如: M.ISomeOtherObject (在方法调用之外)、"ISomeOtherObject“(参数)和M.ISomeOtherObject的设置(在lambda内)之间的断开。
但是,考虑到所有的事情,它比一次又一次地复制和粘贴相同的代码要好得多)。
https://stackoverflow.com/questions/13260191
复制相似问题