WinForm C# 如何将方法附加到以编程方式创建的控件
WinForm C# how attach an Method to a Control programmaticaly created
在我的应用程序中,我以编程方式生成了一堆 DataGridView。我可以向它添加 add/remove 行并从中检索所有数据并将数据复制到另一个 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);
}
现在,我想将方法附加到此控件。我认为最好的方法是在初始化控件时附加它。例如,我会附加一个像这样的方法
public void Action(DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
我试了很多,但不知道怎么做。
谢谢
如@CurleD 所述,您只需将您的方法订阅到特定的 EventHandler。因此,将您的 Action 更改为:
private void panGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
}
然后订阅CellMouseClick
事件:
panGridView.CellMouseClick += panGridView_CellMouseClick;
在我看来,您需要一种特殊的 DataGridView。您想要一个带有附加方法的 DataGridView。您已经了解到,每当您需要一个“class,与另一个 class 非常相似,但只有一点点不同”时,您需要创建一个派生的 class,或者创建一个composition,如果你不想暴露基类的所有方法 class.
class DataGridViewWithAttachedMethod : DataGridView // TODO: invent proper name
{
...
}
class MySpecialDataGridView : UserControl
{
private DataGridView dgv1;
...
}
第一种方法的优点是你的class(=代码,不是操作符)的用户可以访问所有的DataGridView方法,所以使用起来会非常灵活。缺点:他们可以访问所有 DataGridView 方法,因此他们可能会弄乱您的 DataGridView。
您是使用推导还是组合取决于您的 class 需要多简单,换句话说:您是否想公开您不希望被其他人使用的方法?
I want to attach Method to this Control.
这个不是很清楚。你想给 DataGridView 一个额外的方法,总是一样的吗?或者您想动态附加一个方法:dgv1 有另一个附加方法而不是 dgv2。
class DgvWithExtraMethod : ...
{
public void Action(DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
}
}
此 dgv 的所有实例都将具有相同的额外方法。你所要做的就是创建一个这个class的对象,你就会有这个方法
但是,如果您想将不同的方法附加到 class 的实例,您需要一个包含此方法的 属性。
class DgvWithMethod : ...
{
public Action<DataGridViewCellMouseEventArgs> ExtraMethod {get; set;}
}
如果您想要 class 万无一失,请考虑使用“无操作 (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, or if you want to reuse this class (derivation / composition) override 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)
...
在我的应用程序中,我以编程方式生成了一堆 DataGridView。我可以向它添加 add/remove 行并从中检索所有数据并将数据复制到另一个 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);
}
现在,我想将方法附加到此控件。我认为最好的方法是在初始化控件时附加它。例如,我会附加一个像这样的方法
public void Action(DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
我试了很多,但不知道怎么做。
谢谢
如@CurleD 所述,您只需将您的方法订阅到特定的 EventHandler。因此,将您的 Action 更改为:
private void panGridView_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
}
然后订阅CellMouseClick
事件:
panGridView.CellMouseClick += panGridView_CellMouseClick;
在我看来,您需要一种特殊的 DataGridView。您想要一个带有附加方法的 DataGridView。您已经了解到,每当您需要一个“class,与另一个 class 非常相似,但只有一点点不同”时,您需要创建一个派生的 class,或者创建一个composition,如果你不想暴露基类的所有方法 class.
class DataGridViewWithAttachedMethod : DataGridView // TODO: invent proper name
{
...
}
class MySpecialDataGridView : UserControl
{
private DataGridView dgv1;
...
}
第一种方法的优点是你的class(=代码,不是操作符)的用户可以访问所有的DataGridView方法,所以使用起来会非常灵活。缺点:他们可以访问所有 DataGridView 方法,因此他们可能会弄乱您的 DataGridView。
您是使用推导还是组合取决于您的 class 需要多简单,换句话说:您是否想公开您不希望被其他人使用的方法?
I want to attach Method to this Control.
这个不是很清楚。你想给 DataGridView 一个额外的方法,总是一样的吗?或者您想动态附加一个方法:dgv1 有另一个附加方法而不是 dgv2。
class DgvWithExtraMethod : ...
{
public void Action(DataGridViewCellMouseEventArgs e)
{
if(e.RowIndex==2)
{
MessageBox.Show("Hello");
}
}
}
此 dgv 的所有实例都将具有相同的额外方法。你所要做的就是创建一个这个class的对象,你就会有这个方法
但是,如果您想将不同的方法附加到 class 的实例,您需要一个包含此方法的 属性。
class DgvWithMethod : ...
{
public Action<DataGridViewCellMouseEventArgs> ExtraMethod {get; set;}
}
如果您想要 class 万无一失,请考虑使用“无操作 (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, or if you want to reuse this class (derivation / composition) override 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)
...