Best practices on load a form inside a main form, both residing in an external DLL assembly

倖福魔咒の 提交于 2021-01-29 22:41:09

问题


I've loaded an external DLL into your project like this

Dim assembly As Assembly = Assembly.LoadFile(libraryPath & "filename.dll")
Dim type As Type = assembly.[GetType]("NameSpace.ClassName")

// i'm loading as a form here but can be any control
Dim frm As Form = TryCast(Activator.CreateInstance(type), Form)

What are the best practices if you're loading a class or a control inside the loaded form (above) that resides also inside the same assembly ?

for instance: Lets say you loaded an assembly consisted of several forms. You load the assembly and create the instance of one of the forms, frm. But inside the loaded form, frm is also loaded another 2nd form, frm2 also belonging to the same assembly. How do i instantiate the second form? do i need to load the assembly again ?

Edit: The assembly is a. Net 4.8 class library, that holds several forms, modules and abstract classes. Is being loaded into a winforms also in. Net 4.8. This question applies to both VB and C#. But on my case I'm coding on VB.


回答1:


You can load your external assembly in the StartUp event of your application.
Open Project->Properties->Application and click the View Application Events button.
This will open or generate the ApplicationEvents.vb class file (you'll see, in some comments, the events that are more often handled using the My.Application class).

Here, we add a handler to the StartUp event: this event is raised before the application startup form is loaded and shown.
We define a Public class object that references the external Library containing the Form resources.
This public class object is visible by all other classes in the Application, through the My.Application reference.
This class exposes a Public Method, LoadForm(), that allows to load an external Form by Name.

Imports System.IO
Imports System.Reflection
Imports Microsoft.VisualBasic.ApplicationServices

Namespace My
    Partial Friend Class MyApplication

        Public FormResources As ResourceBag

        Protected Overrides Function OnStartup(e As StartupEventArgs) As Boolean
            FormResources = New ResourceBag()
            Return MyBase.OnStartup(e)
        End Function

        Friend Class ResourceBag
            Private Shared libraryPath As String = "[Your Library path]"
            Private Shared asm As Assembly = Nothing
            Public Sub New()
                Dim resoursePath As String = Path.Combine(libraryPath, "[Your .dll Name].dll")
                If File.Exists(resoursePath) Then
                    asm = Assembly.LoadFile(resoursePath)
                End If
            End Sub

            Public Function LoadForm(formName As String) As Form
                If asm Is Nothing Then Throw New BadImageFormatException("Resource Library not loaded")
                Return TryCast(Activator.CreateInstance(asm.GetType($"[Library Namespace].{formName}")), Form)
            End Function
        End Class
    End Class
End Namespace

Now, let's assume you have a Form named Form1 in your external library.
You can make Form1 load another Form from the external Library or a Form from your assembly using either the LoadForm() method (it creates an instance of a Form in the external library) or the New keyword to create an instance of local Form class.

► If Form1 of the external Library already shows another Form from the same Library, e.g., clicking a Button, there's nothing we have to do: the external new Form is generated as usual.

In the sample code that follows, we are instead adding two Buttons to the external Form1 class:

  • One Button loads a Form, Form2, from the external library, using the public method previously defined: Using extForm1 As Form = My.Application.FormResources.LoadForm("Form1")
  • The other Button loads a Form also named Form2, which is instead part of the current Application, using the New keyword: Dim f2 As New Form2()

► The external Form1 instance is created with a Using statement because the ShowDialog() method is used to show the new Form: this requires that we dispose of the Form when it closes, otherwise it cannot dispose of itself when show like this.
If you use Show() or Show(Me), the Using block needs to be removed otherwise the Form will be closed instantly. The Form and its Controls/components will be disposed of when it closes anyway.

► The Form2 Form class of your Application cannot have Controls added from the Application Settings (these Control will be disposed of and generate an exception if the Form is shown a second time)


Using extForm1 As Form = My.Application.FormResources.LoadForm("Form1")
    If extForm1 IsNot Nothing Then
        Dim btnExt = New Button() With {
            .Location = New Point(20, 50),
            .Size = New Size(100, 30),
            .Text = "Lib Form2"
        }
        AddHandler btnExt.Click,
            Sub()
                Dim f2ext = My.Application.FormResources.LoadForm("Form2")
                f2ext.Show()
            End Sub

        Dim btn = New Button() With {
            .Location = New Point(140, 50),
            .Size = New Size(100, 30),
            .Text = "My Form2"
        }
        AddHandler btn.Click,
            Sub()
                Dim f2 As New Form2()
                f2.Show()
            End Sub

        extForm1.Controls.AddRange({btnExt, btn})
        btnExt.BringToFront()
        btn.BringToFront()
        extForm1.StartPosition = FormStartPosition.CenterParent
        extForm1.ShowDialog(Me)
    End If
End Using


来源:https://stackoverflow.com/questions/62589504/best-practices-on-load-a-form-inside-a-main-form-both-residing-in-an-external-d

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!