Mat*_*ley 13 c# events inheritance
在任何情况下是否有可能实现这一目标?
我目前的情况如下:
public class CustomForm : Form
{
public class CustomGUIElement
{
...
public event MouseEventHandler Click;
// etc, and so forth.
...
}
private List<CustomGUIElement> _elements;
...
public void CustomForm_Click(object sender, MouseEventArgs e)
{
// we might want to call one of the _elements[n].Click in here
// but we can't because we aren't in the same class.
}
}
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是有一个类似的功能:
internal enum GUIElementHandlers { Click, ... }
internal void CustomGUIElement::CallHandler(GUIElementHandler h, object[] args) {
switch (h) {
case Click:
this.Click(this, (EventArgs)args[0]);
break;
... // etc and so forth
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常难看的kludge,但它应该工作......虽然必须有一个更优雅的解决方案?.NET库一直使用消息处理程序和Control中的调用事件来执行此操作.还有其他人有其他/更好的想法吗?
Phi*_*ght 25
您只需要添加一个公共方法来调用该事件.Microsoft已针对某些事件执行此操作,例如PerformClick用于公开Click事件的控件.
public class CustomGUIElement
{
public void PerformClick()
{
OnClick(EventArgs.Empty);
}
protected virtual void OnClick(EventArgs e)
{
if (Click != null)
Click(this, e);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您将在示例事件处理程序中执行以下操作...
public void CustomForm_Click(object sender, MouseEventArgs e)
{
_elements[0].PerformClick();
}
Run Code Online (Sandbox Code Playgroud)
c#中的event关键字修改了委托的声明.它阻止直接分配给委托(您只能在事件上使用+ =和 - =),并且它可以防止从类外部调用委托.
所以你可以改变你的代码看起来像这样:
public class CustomGUIElement
{
...
public MouseEventHandler Click;
// etc, and so forth.
...
}
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样从类外部调用事件.
myCustomGUIElement.Click(sender,args);
Run Code Online (Sandbox Code Playgroud)
缺点是使用该类的代码可以使用以下代码非常容易地覆盖任何已注册的处理程序:
myCustomGUIElement.Click = null;
Run Code Online (Sandbox Code Playgroud)
如果将Click委托声明为事件,则不允许这样做.