WinForm C#如何将方法附加到以编程方式创建的控件

Posted

技术标签:

【中文标题】WinForm C#如何将方法附加到以编程方式创建的控件【英文标题】:WinForm C# how attach an Method to a Control programmaticaly created 【发布时间】:2021-10-03 19:16:02 【问题描述】:

在我的应用程序中,我以编程方式生成了一堆 DataGridView。我可以向其中添加/删除行并从中检索所有数据并将数据复制到另一个 DataGrid 中。

例如当我创建它时

public void Example(TabControl tab)
        for(int i=0;i<tab.TabCount;i++)
        
        tab.TabPages.Add("Panneau " + tab.TabCount);
        
        DataGridView panGridView = new DataGridView();
        panGridView.Name = "panGridView_" + tab.TabCount;
        panGridView.Location = new System.Drawing.Point(0, 0);
        panGridView.RowTemplate.Height = 24;
        panGridView.Size = new System.Drawing.Size(1375, 458);
        panGridView.Columns.Add("id", "id");
        panGridView.Columns.Add("part_code", "part_code");
        panGridView.Columns[0].Width = 100;
        panGridView.Columns[1].Width = 150;
        panGridView.Visible = true;
        panIndex.Items.Add(tab.TabCount - 1);
        tab.TabPages[tab.TabCount - 1].Controls.Add(panGridView);

        

现在,我想将 Method 附加到此控件。我认为最好的方法是在初始化控件时附加它。例如,我会附加一个这样的方法

public void Action(DataGridViewCellMouseEventArgs e)

 if(e.RowIndex==2)
 
  MessageBox.Show("Hello");
 

我尝试了很多,但不知道怎么做。

谢谢

【问题讨论】:

为什么不用委托的事件处理程序? 你能告诉我怎么做吗?请举个例子。也许这是正确的方法。谢谢 您是否创建过按钮单击处理程序?在设计器中的表单上放置一个按钮。您的表单的.cs 文件将打开一个点击处理程序消息。同样重要的是,您表单的.designer.cs 文件将添加一行,将您的处理程序订阅到按钮的单击事件。现在选择按钮,转到属性窗格并单击事件按钮。您将看到新的点击处理程序。选择其他一些事件。单击名称旁边的空白单元格,然后按 Enter。您将使用新的处理程序打开。现在单击您的 DGV 并查看它的事件。选择你感兴趣的,然后从那里开始 我认为你需要了解事件处理的概念。 This is a good intro. 和 this one 正是你需要做的 例如:TabControl.Click += ClickEvent. 【参考方案1】:

在我看来,您需要一种特殊的 DataGridView。您想要一个带有附加方法的 DataGridView。您已经了解到,每当您需要一个“类,与另一个类非常相似,但有一点不同”时,如果您不想公开所有方法,则需要创建派生类或进行组合基类。

class DataGridViewWithAttachedMethod : DataGridView   // TODO: invent proper name

    ...


class MySpecialDataGridView : UserControl

    private DataGridView dgv1;

    ...

第一种方法的优点是您的类的用户(= 代码,而不是运算符)可以访问所有 DataGridView 方法,因此使用起来非常灵活。缺点:它们可以访问所有 DataGridView 方法,因此它们可能会弄乱您的 DataGridView。

您将使用派生还是组合取决于您的类需要做到多傻,换句话说:您是否要公开您不希望被其他人使用的方法?

我想将 Method 附加到这个 Control。

这不是很清楚。你想给 DataGridView 一个额外的方法,总是一样的吗?还是要动态附加一个方法:dgv1 有另一个附加的方法而不是 dgv2。

class DgvWithExtraMethod : ...

    public void Action(DataGridViewCellMouseEventArgs e)
    
        if(e.RowIndex==2)
        
             MessageBox.Show("Hello");
        
    

此 dgv 的所有实例都将具有相同的额外方法。你所要做的就是创建这个类的一个对象,你就会有这个方法。

但是,如果你想为类的实例附加不同的方法,你需要一个包含这个方法的属性。

class DgvWithMethod : ...

    public Action<DataGridViewCellMouseEventArgs> ExtraMethod get; set;

如果您希望您的类万无一失,请考虑使用“无操作 (NOP)”初始化方法

private static Action<DataGridViewCellMouseEventArgs> NOP = (e) => ;

public Action<DataGridViewCellMouseEventArgs> ExtraMethod get; set; = NOP;

用法:

DgvWithMethod dgv1 = new DgvWithMethod

    ExtraMethod = (e) =>
    
        if(e.RowIndex==2)
        
             MessageBox.Show("Hello");
        
    

这是您问题的确切答案。但是,我想你想知道的是:如果操作员点击第2行,那么我要执行方法F(),如果他点击第3行,我要执行方法G()

如果这是您想要的,请使用 Visual Studio 设计器在 DataGridView.CellMouseClick 上添加事件处理程序,或者如果您想重用此类(派生/组合)覆盖 DataGridView.OnCellMouseClick。

private void DataGridView1_CellMouseClick(Object sender,
    DataGridViewCellMouseEventArgs e)

    // find out which column is clicked
    switch (e.ColumnIndex)
    
        case 0: // column Id clicked
            this.ProcessColumnIdClick(e);
            break;
        case 1: // column Name clicked
            this.ProcessColumnNameClick(e);
            break;
        ...

但请注意:如果您允许列重新排序,则应将 ColumnIndex 与每列的 DisplayIndex 进行比较。

if (e.ColumnIndex == this.columnId.DisplayIndex)
    this.ProcessColumnIdClick(e);
else if (e.ColumnIndex == this.columnName.DisplayIndex)
    ...

【讨论】:

哇...我认为 OP 正在寻找一个简单的事件订阅。您的回答非常准确! 太棒了!即时通讯正在尝试,并给你消息谢谢!【参考方案2】:

就像@CurleD 所说,您只需将您的方法订阅到特定的EventHandler。所以把你的 Action 改成这样:

private void panGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)

    if(e.RowIndex==2)
    
        MessageBox.Show("Hello");
    

然后订阅CellMouseClick事件:

panGridView.CellMouseClick += panGridView_CellMouseClick;

【讨论】:

以上是关于WinForm C#如何将方法附加到以编程方式创建的控件的主要内容,如果未能解决你的问题,请参考以下文章

C# winform如何登陆web

添加填充到以编程方式创建的UILabel

Mootools:如何将点击功能绑定到以编程方式生成的元素

如何将 segue 标识符添加到以编程方式进行的模态转换?

如何将 GraphQL 查询中的数据传递到以编程方式生成的页面上?

请问C# winform如何实现将一个不规则形状的图片弄成按键?