如何将事件从用户控件引发到另一个表单 vb.net

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43952976/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 20:16:41  来源:igfitidea点击:

How to raise event from user control to another form vb.net

vb.netuser-controlsevent-handlingraiseevent

提问by Areej Qadomi

I am not familiar with user controls. I have user control with OK and Cancel buttons, I add this user control to an empty form during run time, I have another form which I called "Main Form", In the code I open the empty form and add the user control, after that I want to raise an event (on the OK button) from the user control (or from the empty form I don't know!) to the Main form!I searched the net and found way to create an event and raise the event in the same form. I tried to do the same thing between different forms but I don't know how to do that.

我不熟悉用户控件。我有带有 OK 和 Cancel 按钮的用户控件,我在运行时将此用户控件添加到一个空表单中,我有另一个名为“主表单”的表单,在代码中我打开空表单并添加用户控件,之后那我想从用户控制提高(OK按钮)的事件(或空的形式,我不知道!)主窗体!我在网上搜索并找到了创建事件并以相同形式引发事件的方法。我试图在不同的形式之间做同样的事情,但我不知道该怎么做。

create event

创建事件

Public Event OKEvent As EventHandler

raise event

引发事件

Protected Overridable Sub OnbtnOKClick(e As EventArgs)
    AddHandler OKEvent , AddressOf btnOKClickHandler
    RaiseEvent OKEvent(Me, e)
End Sub

event Sub

事件子

Sub btnOKClickHandler(sender As Object, e As EventArgs)
        'Event Handling
        'My event code 
    End Sub

handle my event on btnOK.click event

在 btnOK.click 事件上处理我的事件

Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
        OnbtnOKClick(e)
End Sub

Okey, that all code works in the same form, maybe its messy but that what I found on the net, I want to make similar thing but on different forms, how can I organize my code?

好吧,所有代码都以相同的形式工作,也许它很混乱,但是我在网上找到的东西,我想制作类似的东西但是在不同的形式上,我该如何组织我的代码?

回答by jmcilhinney

You don't raise an event "to" anywhere. The whole point of events is that you don't have to care who is listening. It's up to the whoever wants to react to the event to handle it and whoever raised the event never has to know about them.

您不会在任何地方“向”提出事件。事件的全部意义在于你不必关心谁在听。这取决于想要对事件做出反应的人来处理它,而引发事件的人永远不必知道他们。

So, all you need to do in this case is have the main form handle the appropriate event(s) of the user control. The user control is a control like any other and the event is an event like any other so the main form handles the event of the user control like it would handle any other event of any other control. Where you create the user control, use an AddHandlerstatement to register a handler for the event you declared in the user control.

因此,在这种情况下,您需要做的就是让主窗体处理用户控件的适当事件。用户控件与其他控件一样,事件也是其他控件,因此主窗体处理用户控件的事件就像处理任何其他控件的任何其他事件一样。在创建用户控件的位置,使用AddHandler语句为您在用户控件中声明的事件注册处理程序。

EDIT:

编辑:

The OnbtnOKClickmethod that you have shown above should not look like this:

OnbtnOKClick您上面显示的方法不应如下所示:

Protected Overridable Sub OnbtnOKClick(e As EventArgs)
    AddHandler OKEvent , AddressOf btnOKClickHandler
    RaiseEvent OKEvent(Me, e)
End Sub

but rather like this:

而是像这样:

Protected Overridable Sub OnbtnOKClick(e As EventArgs)
    RaiseEvent OKEvent(Me, e)
End Sub

Also, the btnOKClickHandlermethod should be in the main form, not the user control. As I said in my answer, it's the main form that handles the event. That means that the event handler is in the main form. As I also said, when you create the user control in the main form, that is where you register the event handler, e.g.

此外,该btnOKClickHandler方法应该在主窗体中,而不是在用户控件中。正如我在回答中所说,它是处理事件的主要形式。这意味着事件处理程序在主窗体中。正如我也说过的,当您在主窗体中创建用户控件时,即注册事件处理程序的地方,例如

Dim uc As New SomeUserControl

AddHandler uc.OKEvent, AddressOf btnOKClickHandler

As I hope you have absorbed in your reading, if you use AddHandlerto register an event handler then you need a corresponding RemoveHandlerto unregister it when the object is finished with.

我希望你已经专心阅读,如果你AddHandler用来注册一个事件处理程序,那么你需要一个对应的RemoveHandler在对象完成时取消注册它。

回答by Idle_Mind

If I'm understanding correctly, you have...

如果我理解正确的话,你有...

  1. FormA creates FormB.
  2. FormB creates UserControlB.
  3. UserControlB raises "OK" event.
  4. FormB receives "OK" event.
  1. FormA 创建 FormB。
  2. FormB 创建 UserControlB。
  3. UserControlB 引发“OK”事件。
  4. FormB 接收“OK”事件。

...but you want an additional step of:

...但你想要一个额外的步骤:

  1. FormA receives "OK" event.
  1. FormA 接收“OK”事件。

The problem here is that FormA has no reference to UserControlB because FormB was the one that created the UserControl. An additional problem is that FormB may have no idea who FormA is (depending on how you've got it setup).

这里的问题是 FormA 没有对 UserControlB 的引用,因为 FormB 是创建 UserControl 的那个。另一个问题是 FormB 可能不知道 FormA 是谁(取决于您如何设置它)。

Option 1 - Pass References

选项 1 - 传递引用

If you want both FormB and FormA to respond to a SINGLE"OK" event (generated by the UserControl), then you'd have to somehow have a reference to all three players in the same place so that the event can be properly wired up. The logical place to do this would be in FormB as that is where the UserControl is created. To facilitate that, however, you'd have to modify FormB so that a reference to FormA is somehow passed to it. Then you can wire up the "OK" event directly to the handler in FormA when FormB creates its instance of UserControlB:

如果您希望 FormB 和 FormA 都响应单个“OK”事件(由 UserControl 生成),那么您必须以某种方式在同一位置引用所有三个玩家,以便可以正确连接事件. 执行此操作的合乎逻辑的位置是在 FormB 中,因为这是创建 UserControl 的位置。但是,为了方便起见,您必须修改 FormB,以便以某种方式将 FormA 的引用传递给它。然后,当 FormB 创建其 UserControlB 实例时,您可以将“OK”事件直接连接到 FormA 中的处理程序:

Public Class FormA

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim frmB As New FormB(Me) ' pass reference to FormA into FormB via "Me" and the Constructor of FormB
        frmB.Show()
    End Sub

    Public Sub ucB_OKEvent()
        ' ... do something in here ...
        Debug.Print("OK Event received in FormA")
    End Sub

End Class

Public Class FormB

    Private _frmA As FormA

    Public Sub New(ByVal frmA As FormA)
        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        _frmA = frmA ' store reference to FormA so we can use it later
    End Sub

    Private Sub FormB_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ucB As New UserControlB
        ucB.Location = New Point(10, 10)
        AddHandler ucB.OKEvent, AddressOf _frmA.ucB_OKEvent ' wire up the "OK" event DIRECTLY to the handler in our stored reference of FormA
        Me.Controls.Add(ucB)
    End Sub

End Class

Public Class UserControlB

    Public Event OKEvent()

    Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
        RaiseEvent OKEvent()
    End Sub

End Class

Option 2 - "Bubble" the Event

选项 2 - “冒泡”事件

Another option is "bubble" the event from FormB up to FormA. In this scenario, FormB will have no idea who FormA is, so no reference will be passed. Instead, FormB will have its own "OK" event that is raised in response to receiving the original "OK" event from UserControlB. FormA will get the "OK" notification from the UserControl, just not directly:

另一种选择是将事件从 FormB“冒泡”到 FormA。在这种情况下,FormB 将不知道 FormA 是谁,因此不会传递任何引用。相反,FormB 将拥有自己的“OK”事件,该事件是在从 UserControlB 接收到原始“OK”事件时引发的。FormA 将从 UserControl 获得“OK”通知,而不是直接:

Public Class FormA

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim frmB As New FormB
        AddHandler frmB.OKEvent, AddressOf frmB_OKEvent
        frmB.Show()
    End Sub

    Private Sub frmB_OKEvent()
        ' ... do something in here ...
        Debug.Print("OK Event received from FormB in FormA")
    End Sub

End Class

Public Class FormB

    Public Event OKEvent()

    Private Sub FormB_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim ucB As New UserControlB
        ucB.Location = New Point(10, 10)
        AddHandler ucB.OKEvent, AddressOf ucB_OKEvent
        Me.Controls.Add(ucB)
    End Sub

    Private Sub ucB_OKEvent()
        Debug.Print("OK Event received from UserControl in FormB")
        RaiseEvent OKEvent()
    End Sub

End Class

Public Class UserControlB

    Public Event OKEvent()

    Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
        RaiseEvent OKEvent()
    End Sub

End Class

Design Decisions

设计决策

You have to make a design decision here. Who is the source of the "OK" event? Should it be the UserControl or FormB? Will the UserControl ever be used in different forms (other than FormB)? Will FormB ever be used with Forms other then FormA? These answers may help you decide which approach is better...or may lead you to rethink how you've designed your current solution; you may need to change it altogether.

你必须在这里做出设计决定。谁是“OK”事件的源头?应该是 UserControl 还是 FormB?UserControl 是否会以不同的形式(FormB 除外)使用?FormB 是否会与 FormA 以外的 Forms 一起使用?这些答案可能会帮助您决定哪种方法更好……或者可能会引导您重新思考您是如何设计当前解决方案的;你可能需要彻底改变它。