将子控件的点击事件传递给父控件

19
我有一个Windows窗体,其中包含一个面板,里面包含另一个从Windows Forms派生的类。它被作为控件包含在该面板中,并且它本身包含两个按钮。
我希望子控件的事件能够传递到父窗口。例如,面板中的子窗口有一个“取消”按钮,用于关闭它。我希望父控件,即主窗口也能关闭,但是如何拦截子控件的按钮单击事件呢?
如果没有其他合适的方法来实现这一点,我可以修改子控件,但是我更愿意避免这样做。

您提供的问题描述与标题不同。您想要什么?您是否希望在单击子控件时触发父窗体的单击事件?您是否希望在单击子控件中的按钮时关闭父窗体?还是其他什么? - Reza Aghaei
用户将点击子控件上的按钮 - 除了子控件上的某些事件外,甚至父控件也需要执行一些操作,但我不确定如何向父控件发出信号,表明子控件已触发某个事件。这些操作可能是通用操作,例如关闭所有窗体,也可能是更复杂的操作。但父控件需要知道子控件上已触发了一个事件。 - user1173240
虽然您可以直接从子窗体与父窗体进行交互,但最好是通过子控件引发一些事件,并在父窗体中订阅这些事件。 - Reza Aghaei
1个回答

37

虽然你可以直接从子表单与父表单交互,例如this.ParentForm.Close(),但更好的方式是由子控件引发一些事件,并在父表单中订阅这些事件。

从子控件引发事件:

public event EventHandler CloseButtonClicked;
protected virtual void OnCloseButtonClicked(EventArgs e)
{
    CloseButtonClicked?.Invoke(this, e);
}
private void CloseButton_Click(object sender, EventArgs e)
{
    OnCloseButtonClicked(e);
}

注意: 要触发XXXX事件,只需要调用XXXX事件委托即可;创建protected virtual OnXXXX的原因仅是为了遵循模式,以便让派生类在触发事件之前/之后重写该方法并自定义行为。

在父级中订阅和使用事件:

//Subscribe for event using designer or in constructor or form load
this.userControl11.CloseButtonClicked += userControl11_CloseButtonClicked;

//Close the form when you received the notification
private void userControl11_CloseButtonClicked(object sender, EventArgs e)
{
    this.Close();
}

了解更多关于事件的内容,请查看:


谢谢您。我将检查是否可以修改子控件。 - user1173240
1
@tCoe 把它放在 InitializeComponent 后面是正确的,应该可以工作。可能事件根本没有被触发,因为您可能忘记将 CloseButton_Click 分配给 CloseButtonClick 事件。 - Reza Aghaei
为了更简单的代码实现,您可以在子类中执行以下操作:public event EventHandler CloseButtonClicked; private void btnOK_Click( object sender, EventArgs e ) { CloseButtonClicked?.Invoke( this, e ); } - TheSteelDuck
2
@ClausMøllerJørgensen 感谢您的反馈,是的,我们可以为这部分 CloseButtonClicked?.Invoke( this, e ); 进行特殊处理。但是... 有一个原因需要使用 OnCloseButtonClicked,遵循 .NET 的标准事件模式,并且为开发人员提供覆盖虚拟 OnCloseButtonClicked 方法的机会。 - Reza Aghaei
1
@WilliamMartens,在那个评论时间,我还不习惯使用Visual Studio将code.cs和code.designer.cs分开的方式,有好几次我错过了“使用设计器订阅事件”的步骤... - Marcelo Scofano Diniz
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接