在主窗体中加载窗体的最佳实践,它们都驻留在外部 DLL 程序集中 [英] Best practices on load a form inside a main form, both residing in an external DLL assembly

查看:19
本文介绍了在主窗体中加载窗体的最佳实践,它们都驻留在外部 DLL 程序集中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经像这样将外部 DLL 加载到您的项目中

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 ?

例如:假设您加载了一个由多个表单组成的程序集.您加载程序集并创建其中一种窗体 frm 的实例.但是在加载的表单中,frm 还加载了另一个第二个表单,frm2 也属于同一个程序集.我如何实例化第二种形式?我需要再次加载程序集吗?

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 ?

编辑:大会是一个.Net 4.8 类库,包含多个表单、模块和抽象类.正在加载一个winforms也在.net 4.8中.这个问题同时适用于 VB 和 C#.但就我而言,我正在使用 VB 进行编码.

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.

推荐答案

您可以在应用程序的 StartUp 事件中加载外部程序集.
打开Project->Properties->Application,然后点击View Application Events按钮.
这将打开或生成 ApplicationEvents.vb 类文件(在某些注释中,您将看到更经常使用 My.Application 类处理的事件).

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).

在这里,我们为 StartUp 事件添加一个处理程序:在加载和显示应用程序启动表单之前引发此事件.
我们定义了一个 Public 类对象,该对象引用包含表单资源的外部库.
通过 My.Application 引用,应用程序中的所有其他类都可以看到此公共类对象.
该类公开了一个公共方法,LoadForm(),它允许按名称加载外部表单.

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

现在,假设您的外部库中有一个名为 Form1 的表单.
您可以使用 LoadForm() 方法使 Form1 从外部库中加载另一个表单或从您的程序集中加载一个表单(它在外部库中创建一个表单实例) 或 New 关键字来创建本地 Form 类的实例.

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.

► 如果外部库的 Form1 已经显示来自同一个库的另一个表单,例如,单击一个按钮,我们无需做任何事情:外部新表单照常生成.

► 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.

在下面的示例代码中,我们改为向外部 Form1 类添加两个按钮:

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

  • 一个按钮从外部库加载一个表单,Form2,使用之前定义的公共方法:Using extForm1 As Form = My.Application.FormResources.LoadForm("Form1";)
  • 另一个按钮加载一个名为 Form2 的表单,它是当前应用程序的一部分,使用 New 关键字:Dim f2 As New Form2()
  • 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()

► 外部 Form1 实例是使用 Using 语句创建的,因为 ShowDialog() 方法用于显示新的 Form:这需要我们在 Form 关闭时对其进行处理,否则不能像这样展示时自行处理.
如果您使用 Show()Show(Me),则需要删除 Using 块,否则表单将立即关闭.无论如何,该窗体及其控件/组件在关闭时都会被处理掉.

► 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.

► 您的应用程序的 Form2 表单类不能从应用程序设置添加控件(如果表单第二次显示,这些控件将被处理并生成异常)

► 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

这篇关于在主窗体中加载窗体的最佳实践,它们都驻留在外部 DLL 程序集中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆