如何在不知道哪个表单加载到面板的情况下调用Sub?

时间:2014-10-15 10:44:10

标签: vb.net winforms events

在每个DataGridView1_SelectionChanged事件中,我需要运行加载到Panel1中的Private Sub OnSelectionChanged()表单(请参阅图像http://tinypic.com/r/2nu2wx/8)。

每个可以加载到Panel1中的表单都具有相同的Private Sub OnSelectionChanged(),可以启动所有必要的计算。例如,我可以加载一个计算温度的表格,或者我可以加载一个计算电压的表格。如果在主窗体的DataGridView1中选择了不同的元素,则应重新计算温度或电压。

问题是 - 有很多表单可以加载到Panel1中,我很难提出一个只会触发一次的事件,并且只会在加载的表单中运行必要的Sub。

目前我正在使用Shared Event

'Main form (Form1).
Shared Event event_UpdateLoadedForm(ByVal frm_name As String)

'This is how I load forms into a panel (in this case frm_SCT).
Private Sub mnu_SCT_Click(sender As Object, e As EventArgs) Handles mnu_SCT.Click
    frm_SCT.TopLevel = False
    frm_SCT.Dock = DockStyle.Fill
    Panel1.Controls.Add(frm_SCT)
    frm_SCT.Show()
    Var._loadedForm = frm_SCT.Name
    RaiseEvent event_UpdateLoadedForm(Var._loadedForm)
End Sub

‘Form that is loaded into panel (Form2 or Form3 or Form4...).
Private WithEvents myEvent As New Form1

Private Sub OnEvent(ByVal frm_name As String) Handles myEvent.event_UpdateLoadedForm
    ‘Avoid executing code for the form that is not loaded.
    If frm_name <> Me.Name Then Exit Sub
End Sub

这种方法有效,但我确信它可以做得更好(我感谢任何建议)。我试图像这样在主窗体中引发一个事件:

Public Event MyEvent As EventHandler

Protected Overridable Sub OnChange(e As EventArgs)
    RaiseEvent MyEvent(Me, e)
End Sub

Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
    Handles DataGridView1.SelectionChanged
    OnChange(EventArgs.Empty)
End Sub

但我不知道以加载的形式订阅它。

谢谢。

1 个答案:

答案 0 :(得分:0)

考虑到Hans Passant的评论以及他在相关主题中发布的代码,我实现了我想要的(见下面的代码)。

Public Interface IOnEvent
    Sub OnSelectionChange()
End Interface

Public Class Form1    
    ' ???
    Private myInterface As IOnEvent = Nothing

    ' Create and load form.
    Private Sub DisplayForm(frm_Name As String)

        ' Exit if the form is already displayed.
        If Panel1.Controls.Count > 0 AndAlso _
            Panel1.Controls(0).GetType().Name = frm_Name Then Exit Sub

        ' Dispose previous form.
        Do While Panel1.Controls.Count > 0
            Panel1.Controls(0).Dispose()
        Loop

        ' Create form by its full name.
        Dim T As Type = Type.GetType("Namespace." & frm_Name)
        Dim frm As Form = CType(Activator.CreateInstance(T), Form)

        ' Load form into the panel.
        frm.TopLevel = False
        frm.Visible = True
        frm.Dock = DockStyle.Fill
        Panel1.Controls.Add(frm)

        ' ???
        myInterface = DirectCast(frm, IOnEvent)

    End Sub

    Private Sub DataGridView1_SelectionChanged(sender As Object, e As EventArgs) _
        Handles DataGridView1.SelectionChanged

        ' Avoid error if the panel is empty.
        If myInterface Is Nothing Then Return

        ' Run subroutine in the loaded form.
        myInterface.OnSelectionChange()

    End Sub
End Class

最后一件事 - 如果有人可以快速查看代码(它可以工作)并确认它没问题会很好,特别是标有“???”的行(我还不明白它们) )。