如何在 GUI 事件上调用回调函数?代表?
How to call a callback function on a GUI event? Delegates?
我是 C# 的新手,我想知道在这里使用委托是否正确:
我在 Visual Studio Windows Forms Designer 中创建了一个 UserControl。
在 TableLayoutPanel 中,我有 3 x 3 个这样的用户控件。他们每个人都通过构造函数获得一个行和列索引。
现在,在我包含 TableLayoutPanel 的表单中,我想在单击其中一个 UserControl 时调用一个函数,并在该函数调用中包含行和列索引。
我知道如何处理 UserControl 中的 Click 事件。但我不知道如何调用某种可以向 UserControl 注册的回调。
所以 UserControl 的 Click 事件处理程序会调用类似 Callback(Row, Col);
的东西
但我不知道如何将我的窗体的方法获取到用户控件中。在 C 中,我会使用函数指针。我这里需要代表吗?
所以在我的 UserControl 部分 class 我会有这样的东西:
public delegate void DoubleClickHandler(int row, int col);
public DoubleClickHandler Callback;
public void On_Click(object sender, EventArgs e)
{
Callback(Row, Col);
}
创建表单时我会做类似的事情:
MyControl elem = new MyControl(1, 3);
elem.Callback = delegate (int row, int col) { Console.WriteLine("row {0}, col {1}", row, col); }
它有效,但我不知道这是否是正确的方法。
Winforms 可能会为此使用事件;相同的想法,不同的关键字例如
活动道具
//old
public DoubleClickHandler Callback;
//new
public event EventHandler<(int Row, int Col)> SomethingDoubleClicked; //use a past tense name if you raise after, or a "SomethingDoubleClicking" if you raise before - probably hard to raise a click event before but..
OnClick 可能有这样的代码
var eh = SomethingDoubleClicked;
eh?.Invoke(this, (theRow, theCol));
订阅可能如下所示:
//"modern"
yourcontrol.SomethingDoubleClicked += (s, e) => Console.WriteLine("row {0}, col {1}", e.Row, e.Col);
//"classic"
yourcontrol.SomethingDoubleClicked += SomeControl_SomethingDoubleClicked;
void SomeControl_SomethingDoubleClicked(object sender, (int Row, int Col) e)
{
Console.WriteLine("row {0}, col {1}", e.Row, e.Col);
}
注意 +=
而不是 =
- event
在概念上是一个方法列表,应该以未定义的顺序调用
随意将 EventHandler 中的元组更改为 class 或其他内容。也可以从 EventArgs 派生,但不是必须的。
如果您没有要报告的用户状态,您可以简化为使用:
public event EventHandler SomethingDoubleClicked;
//onclick
var eh = SomethingDoubleClicked;
eh?.Invoke(this, EventArgs.Empty);
ourcontrol.SomethingDoubleClicked += (s, e) => ...;
但我可能会避免从 EventArgs 派生以提供自定义用户状态,然后使用上面的 EventHandler 表单 - 它会起作用,因为当你这样做时:
eh?.Invoke(this, new MyCustomEventArgs(...));
MyCustomEventArgs 派生自 EventArgs,因此您可以在父类型中传递子 class,但这意味着使用它的开发人员必须将其转换回去:
void SomeControl_SomethingDoubleClicked(object sender, EventArgs e)
{
var mcea = e as MyCustomEventArgs;
}
而且有点恶心;最好使用 EventHandler<MyCustomEvenArgs>
使其成为 TAB TAB/no 转换事件
我是 C# 的新手,我想知道在这里使用委托是否正确:
我在 Visual Studio Windows Forms Designer 中创建了一个 UserControl。 在 TableLayoutPanel 中,我有 3 x 3 个这样的用户控件。他们每个人都通过构造函数获得一个行和列索引。
现在,在我包含 TableLayoutPanel 的表单中,我想在单击其中一个 UserControl 时调用一个函数,并在该函数调用中包含行和列索引。
我知道如何处理 UserControl 中的 Click 事件。但我不知道如何调用某种可以向 UserControl 注册的回调。
所以 UserControl 的 Click 事件处理程序会调用类似 Callback(Row, Col);
但我不知道如何将我的窗体的方法获取到用户控件中。在 C 中,我会使用函数指针。我这里需要代表吗?
所以在我的 UserControl 部分 class 我会有这样的东西:
public delegate void DoubleClickHandler(int row, int col);
public DoubleClickHandler Callback;
public void On_Click(object sender, EventArgs e)
{
Callback(Row, Col);
}
创建表单时我会做类似的事情:
MyControl elem = new MyControl(1, 3);
elem.Callback = delegate (int row, int col) { Console.WriteLine("row {0}, col {1}", row, col); }
它有效,但我不知道这是否是正确的方法。
Winforms 可能会为此使用事件;相同的想法,不同的关键字例如
活动道具
//old
public DoubleClickHandler Callback;
//new
public event EventHandler<(int Row, int Col)> SomethingDoubleClicked; //use a past tense name if you raise after, or a "SomethingDoubleClicking" if you raise before - probably hard to raise a click event before but..
OnClick 可能有这样的代码
var eh = SomethingDoubleClicked;
eh?.Invoke(this, (theRow, theCol));
订阅可能如下所示:
//"modern"
yourcontrol.SomethingDoubleClicked += (s, e) => Console.WriteLine("row {0}, col {1}", e.Row, e.Col);
//"classic"
yourcontrol.SomethingDoubleClicked += SomeControl_SomethingDoubleClicked;
void SomeControl_SomethingDoubleClicked(object sender, (int Row, int Col) e)
{
Console.WriteLine("row {0}, col {1}", e.Row, e.Col);
}
注意 +=
而不是 =
- event
在概念上是一个方法列表,应该以未定义的顺序调用
随意将 EventHandler 中的元组更改为 class 或其他内容。也可以从 EventArgs 派生,但不是必须的。
如果您没有要报告的用户状态,您可以简化为使用:
public event EventHandler SomethingDoubleClicked;
//onclick
var eh = SomethingDoubleClicked;
eh?.Invoke(this, EventArgs.Empty);
ourcontrol.SomethingDoubleClicked += (s, e) => ...;
但我可能会避免从 EventArgs 派生以提供自定义用户状态,然后使用上面的 EventHandler 表单 - 它会起作用,因为当你这样做时:
eh?.Invoke(this, new MyCustomEventArgs(...));
MyCustomEventArgs 派生自 EventArgs,因此您可以在父类型中传递子 class,但这意味着使用它的开发人员必须将其转换回去:
void SomeControl_SomethingDoubleClicked(object sender, EventArgs e)
{
var mcea = e as MyCustomEventArgs;
}
而且有点恶心;最好使用 EventHandler<MyCustomEvenArgs>
使其成为 TAB TAB/no 转换事件