winformc#如何将方法附加到通过编程创建的控件上



在我的应用程序中,我以编程方式生成了一堆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");
}

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

感谢

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

class DataGridViewWithAttachedMethod : DataGridView   // TODO: invent proper name
{
...
}
class MySpecialDataGridView : UserControl
{
private DataGridView dgv1;
...
}

第一个方法的优点是类的用户(=代码,而不是操作符)可以访问所有DataGridView方法,因此使用起来非常灵活。缺点:他们可以访问所有的DataGridView方法,所以他们可以弄乱你的DataGridView。

是使用派生还是组合取决于你的类需要有多蠢,换句话说:你想公开你不希望被其他人使用的方法吗?

我想把Method附加到这个控件。

这不是很清楚。你想给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)
...

就像上面所说的@ curl一样,您只需将您的方法订阅到特定的EventHandler。所以把Action改成:

private void panGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
}

然后订阅CellMouseClick事件:

panGridView.CellMouseClick += panGridView_CellMouseClick;

最新更新