其他表单操作后调用表单方法

时间:2014-10-26 09:11:05

标签: vb.net

我遇到了一些问题。我在我的应用程序中有mdi表单我有第一个表单,我使用按钮单击。我想如果点击这个按钮我的第二个表格(如果它打开)提高它的方法。请注意,第二种形式不是第一种形式的孩子(然后我将传递给它的构造函数),但在这里它们是分开的。怎么做?到目前为止我尝试的是:

第一种形式:

Public Class FrmFirst

    Public Event Start(ByVal sender As Object, ByVal e As System.EventArgs)

    Public Sub btnAdd_Click(sender As System.Object, e As System.EventArgs) Handles btnAdd.Click
        Some code...
            RaiseEvent Start(Me, e)  'raise event
    End Sub

第二种形式:

Public Class FrmSecond

'Static
    Public WithEvents MySender As FrmFirst

'method which should be executed
 Public Sub alejaja(sender As System.Object, e As System.EventArgs) Handles MySender.Start
        ReloadGrid()
End Sub

更新

可以从toolsstrip标签打开FrmFirst:

  Private Sub ToolStripLabelFrmFirst _Click(sender As System.Object, e As System.EventArgs) Handles ToolStripLabelFrmFirst.Click
        Dim First As New FrmFirst 
            First.MdiParent = Me
            First.Show()
    End Sub

FrmSecond可以从其他toolsstriplabel中以相同的方式打开:

   Private Sub ToolStripLabelFrmSecond_Click(sender As System.Object, e
As System.EventArgs) Handles ToolStripLabelFrmSecond.Click
         Dim Second As New FrmSecond()
             Second.MdiParent = Me
             Second.Show()
     End Sub

2 个答案:

答案 0 :(得分:1)

您的 MySender 变量始终为Nothing,您永远不会对其进行初始化。所以它也不会发现任何事件。你在这里违反了设计模式,一个表格类别不应该对另一个表格类别有任何了解。除了您的MDI父类之外,它必须知道所有这些,因为它创建了它们的实例。

通过将ReloadGrid()方法设为public来开始修复此问题。在您的MDI父表单中,编写用于跟踪FrmFirst生命周期的代码,以便您可以在必要时正确更新它。像这样:

Private FrmFirst First;

Private Sub ToolStripLabelFrmFirst _Click(sender As System.Object, e As System.EventArgs) Handles ToolStripLabelFrmFirst.Click
    If First IsNot Nothing Then
        First.WindowState = FormWindowState.Normal
    Else
        First = New FrmFirst 
        First.MdiParent = Me
        AddHandler First.FormClosed, Sub(s, ea)
                                         First = Nothing
                                     End Sub
    End Sub
    First.Show()
End Sub

现在,您可以使用第二种形式触发的事件更新网格:

Private Sub ToolStripLabelFrmSecond_Click(sender As System.Object, e As System.EventArgs) Handles ToolStripLabelFrmSecond.Click
    Dim Second As New FrmSecond()
    Second.MdiParent = Me
    AddHandler Second.Start, Sub(s, ea)
                                 If First IsNot Nothing Then First.ReloadGrid()
                             End Sub
    Second.Show()
End Sub

未经测试,应该关闭。

答案 1 :(得分:0)

您应该为从FrmFirst实例接收事件的事件创建一个“hub”,并将它们分派到FrmSecond个实例。我们可以使用主窗体,因为它在两个类中都有引用。

在您的主表单中,为您创建的每个Start实例添加Start事件并处理FrmFirst事件:

Public Event Start(ByVal sender As Object, ByVal e As System.EventArgs)

' Start events raised from every FrmFirst instance will invoke this method
Private Sub First_Start(ByVal sender As Object, ByVal e As System.EventArgs)
    ' And this will invoke every FrmSecond instance's event handlers
    RaiseEvent Start(sender, e)
End Sub

Private Sub ToolStripLabelFrmFirst _Click(sender As System.Object, e As System.EventArgs) Handles ToolStripLabelFrmFirst.Click
    Dim First As New FrmFirst 
    First.MdiParent = Me
    AddHandler First.Start , AddressOf First_Start
    First.Show()
End Sub

然后在创建FrmSecond实例时为此新事件添加处理程序:

Private Sub ToolStripLabelFrmSecond_Click(sender As System.Object, _
             e As System.EventArgs) Handles ToolStripLabelFrmSecond.Click
     Dim Second As New FrmSecond()
     Second.MdiParent = Me
     AddHandler Me.Start, AddressOf Second.alejaja ' This will make the object receive Start events from FrmMain

     Second.Show()
End Sub

当然,您应该在Forms的Closed事件上使用RemoveHandler来防止内存泄漏。这是FrmSecond内部的方式:

Private Sub Form_Closed(ByVal sender As Object, _
    ByVal e As System.EventArgs) Handles MyBase.Closed

    ' Replace Form1 with your Mdi parent form's class name
    RemoveHandler CType(Me.MdiParent, Form1).Start, AddressOf Me.alejaja 
End Sub