首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Winforms控件和“通用”事件处理程序。我该怎么做呢?

Winforms控件和“通用”事件处理程序。我该怎么做呢?
EN

Stack Overflow用户
提问于 2012-11-07 06:05:35
回答 1查看 523关注 0票数 0

在ObjectListView控件的演示中,有以下代码(在"Complex Example“选项卡页中),以允许自定义编辑器( ComboBox) (根据我的情况进行修改,为清楚起见进行了编辑):

代码语言:javascript
复制
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是小菜一碟:

代码语言:javascript
复制
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中,我必须分别区分每种情况:

代码语言:javascript
复制
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:我希望能够做这样的事情:

代码语言:javascript
复制
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#有这样的东西。

那么,有没有人有其他的想法来解决这个问题呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-08 00:58:24

找到了。向Tejs致敬!

代码语言:javascript
复制
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:

代码语言:javascript
复制
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内)之间的断开。

但是,考虑到所有的事情,它比一次又一次地复制和粘贴相同的代码要好得多)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13260191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档