Frage

I'm not sure how to put this so the title may seem a little strange. I have a VB.NET MDI Winform application. In this app when I click a menuitem a child window is opened. To handle what child window must be opened I have case statement in my ToolStripMenuItem_Click event. The problem is that in every case-item the code is nearly the same. So I was wondering if it would be possible to have a general function so the code becomes more readable.

Example:

 Case "mnuPrint"
            Dim ChildWindowFound As Boolean = False

            If Not (MdiChildren.Length.Equals(0)) Then
                For Each ChildWindow As Form In MdiChildren
                    If ChildWindow.Name.Equals("Form1") Then
                        ChildWindow.Activate()
                        ChildWindowFound = True
                    End If
                Next
            End If

            If Not ChildWindowFound Then
                Dim childForm As New Form1()
                childForm.Name = "Form1"
                childForm.MdiParent = Me
                childForm.Show()
            End If
    Case "mnuSearch"
            Dim ChildWindowFound As Boolean = False

            If Not (MdiChildren.Length.Equals(0)) Then
                For Each ChildWindow As Form In MdiChildren
                    If ChildWindow.Name.Equals("Form2") Then
                        ChildWindow.Activate()
                        ChildWindowFound = True
                    End If
                Next
            End If

            If Not ChildWindowFound Then
                Dim childForm As New Form2()
                childForm.Name = "Form2"
                childForm.MdiParent = Me
                childForm.Show()
            End If

As you can see the code is nearly the same but with different forms, here Form1 and Form2 which are different, but it can be many different forms of course. The function I'm talking about would look something like:

 Public Sub OpenNewForm(ByVal frm As Form, ByVal parent As Form, ByVal singleInstance As Boolean)
    Dim ChildWindowFound As Boolean = False

    If Not (parent.MdiChildren.Length.Equals(0)) Then
        For Each ChildWindow As Form In parent.MdiChildren
            If ChildWindow.Name.Equals(frm.Name) Then
                ChildWindow.Activate()
                ChildWindowFound = True
            End If
        Next
    End If

    If Not ChildWindowFound Then
        Dim childForm As New Form
        childForm.Name = frm.Name
        childForm.MdiParent = Me
        childForm.Show()
    End If
End Sub

This doesn't work because I pass the parameters (first two) as Form-type, where it should be Form1 and ParentForm for example, not Form. I think it is possible, just don't know where to start. May be using reflection or something?

UPDATE:

Based on the answers given I came up with this code which is working fine:

 'Code contributed by Rod Paddock (Dash Point Software)
'www.dashpoint.com
'Dim oForm As Form = ObjectFactory.CreateAnObject("MyApplication.frmTwo")
'oForm.Show()
Public Shared Function CreateAnObject(ByVal ObjectName As String) As Object
    Dim Assem = [Assembly].GetExecutingAssembly()

    Dim myType As Type = Assem.GetType(ObjectName.Trim)
    Dim o As Object = Nothing
    Try
        o = Activator.CreateInstance(myType)
    Catch oEx As TargetInvocationException
        MessageBox.Show(oEx.ToString)
    End Try

    Return o
End Function

Public Shared Sub ActivateChildWindow(ByVal frmName As String, ByRef ParentMDIWindow As Form)

    Dim ChildWindowFound As Boolean = False
    With ParentMDIWindow
        If Not (.MdiChildren.Length.Equals(0)) Then
            For Each ChildWindow As Form In .MdiChildren
                If ChildWindow.Name.Equals(frmName) Then
                    ChildWindow.Activate()
                    ChildWindowFound = True
                End If
            Next
        End If
    End With

    If Not ChildWindowFound Then
        Dim childForm As Form = CreateAnObject(frmName)
        childForm.Name = frmName
        childForm.MdiParent = ParentMDIWindow
        childForm.Show()
    End If
War es hilfreich?

Lösung

Maybe something like this can help you:

Dim myForm As Form = Nothing
Dim FormName As String = String.Empty
Dim formType As Type

Select Case Options
   Case "mnuPrint"
       FormName = "Form1"
       myForm = getWindowByName(FormName)

   Case "mnuSearch"
       FormName = "Form2"
       myForm = getWindowByName(FormName)
End Select

If myForm Is Nothing Then
   formType = Type.GetType("WindowsApplication2." + FormName) 'WindowsApplication2 is my project's name
   myForm = Activator.CreateInstance(formType)
   myForm.Name = FormName
   myForm.MdiParent = Me
   myForm.Show()
Else
   myForm.Activate()
End If

And the function:

 Function getWindowByName(ByVal FormName As String) As Form
        Dim frm As Form = Nothing
        If Not (MdiChildren.Length.Equals(0)) Then
            For Each ChildWindow As Form In MdiChildren
                If ChildWindow.Name.Equals(FormName) Then
                    frm = ChildWindow
                End If
            Next
        End If

        Return frm
    End Function

Andere Tipps

See if this will get you started. Create a project with three forms, form1 with two buttons on. Then, add this code to Form1:

Public Class Form1

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click, Button2.Click
        Dim t As Type
        Select Case sender.name
            Case "Button1"
                t = GetType(Form2)

            Case "Button2"
                t = GetType(Form3)
        End Select

        Dim f = System.Activator.CreateInstance(t)
        f.show()
    End Sub
End Class
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top