我不熟悉用户控件。我有用户控制的OK和Cancel按钮,我在运行时将这个用户控件添加到一个空表单,我有另一个表单,我打电话给#34; Main Form",在代码中打开空表单并添加用户控件,之后我想从用户控件(或从我不知道的空白表单!)向主表单引发事件(在“确定”按钮上)! 我在网上搜索并找到了创建事件的方法,并以相同的形式提升事件。我尝试在不同形式之间做同样的事情,但我不知道该怎么做。
创建活动
Public Event OKEvent As EventHandler
举起活动
Protected Overridable Sub OnbtnOKClick(e As EventArgs)
AddHandler OKEvent , AddressOf btnOKClickHandler
RaiseEvent OKEvent(Me, e)
End Sub
事件Sub
Sub btnOKClickHandler(sender As Object, e As EventArgs)
'Event Handling
'My event code
End Sub
在btnOK.click事件上处理我的事件
Private Sub btnOK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
OnbtnOKClick(e)
End Sub
Okey,所有代码都以相同的形式工作,也许它很乱,但是我在网上发现的东西,我想做出类似的东西,但是在不同的形式上,我该如何组织我的代码?
答案 0 :(得分:1)
你不会举办活动"到#34;任何地方。事情的重点在于你不必关心谁在倾听。这取决于想要对事件做出反应的人来处理事件,无论谁提出事件都不需要了解它们。
因此,在这种情况下您需要做的就是让主窗体处理用户控件的相应事件。用户控件是一个像任何其他控件一样的控件,事件就像任何其他事件一样,因此主窗体处理用户控件的事件,就像处理任何其他控件的任何其他事件一样。在创建用户控件的位置,使用AddHandler
语句为您在用户控件中声明的事件注册处理程序。
编辑:
您在上面显示的OnbtnOKClick
方法不应如下所示:
Protected Overridable Sub OnbtnOKClick(e As EventArgs)
AddHandler OKEvent , AddressOf btnOKClickHandler
RaiseEvent OKEvent(Me, e)
End Sub
但是喜欢这样:
Protected Overridable Sub OnbtnOKClick(e As EventArgs)
RaiseEvent OKEvent(Me, e)
End Sub
此外,btnOKClickHandler
方法应该是主窗体,而不是用户控件。正如我在回答中所说,它是处理事件的主要形式。这意味着事件处理程序是主窗体。正如我所说,当你在主窗体中创建用户控件时,就是你注册事件处理程序的地方,例如。
Dim uc As New SomeUserControl
AddHandler uc.OKEvent, AddressOf btnOKClickHandler
由于我希望你已经专注于阅读,如果你使用AddHandler
来注册一个事件处理程序,那么你需要一个相应的RemoveHandler
来在对象完成时取消注册它。
答案 1 :(得分:1)
如果我理解正确,你有......
...但您需要额外的一步:
这里的问题是FormA没有引用UserControlB,因为FormB是创建UserControl的那个。另一个问题是FormB可能不知道FormA是谁(取决于你如何设置它)。
如果您希望FormB和FormA都回复 SINGLE " OK"事件(由UserControl生成),然后您必须以某种方式引用同一位置的所有三个玩家,以便可以正确连接事件。执行此操作的逻辑位置将在FormB中,因为这是创建UserControl的位置。但是,为了方便起见,您必须修改FormB,以便以某种方式将对FormA的引用传递给它。然后你可以连接" OK"当FormB创建UserControlB的实例时,事件直接发送到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
另一个选择是" bubble"从FormB到FormA的活动。在这种情况下,FormB将不知道FormA是谁,因此不会传递任何引用。相反,FormB将拥有自己的" OK"因收到原稿而被提出的事件" OK"来自UserControlB的事件。 FormA将获得" OK"来自UserControl的通知,而不是直接:
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
你必须在这做出设计决定。谁是" OK"的来源?事件?应该是UserControl还是FormB? UserControl是否会以不同的形式使用(FormB除外)? FormB是否会与FormA之外的表格一起使用?这些答案可以帮助您确定哪种方法更好......或者可能会让您重新考虑如何设计当前的解决方案;你可能需要完全改变它。