Vb.net 使用旧对象实例/以前的对象实例

Vb.net 使用旧对象实例/以前的对象实例,vb.net,Vb.net,在VisualBasic2008Express中,我想引用一个表单。但是,当我将Dim main menu作为New main menu输入时,会创建一个新实例。当我想使用表单2中的按钮更改表单主菜单中的标签时,我必须执行以下操作: Dim mainmenu As New MainMenu Dim pitchint As Integer pitchint = Val(Pitch_txt.Text) 'simple way will filter out trailing

在VisualBasic2008Express中,我想引用一个表单。但是,当我将
Dim main menu作为New main menu
输入时,会创建一个新实例。当我想使用表单2中的按钮更改表单主菜单中的标签时,我必须执行以下操作:

    Dim mainmenu As New MainMenu
    Dim pitchint As Integer
    pitchint = Val(Pitch_txt.Text) 'simple way will filter out trailing non-numerics input
    If pitchint > 720 Then
        pitchint -= 720
    ElseIf pitchint > 360 Then
        pitchint -= 360
    End If

    Pitch_txt.Text = pitchint '<--put this line here will solve your "070" issue
    mainmenu.Pitchlbl.Text = pitchint
    If Pitch_txt.Text.Length <> 0 Then
        If Pitchlbl.Text <> Pitch_txt.Text Then
            Pitchlbl.Text = Pitch_txt.Text
        End If
    End If

    Dim yawint As Integer
    yawint = Val(Yaw_txt.Text) 'simple way will filter out trailing non-numerics input
    If yawint > 90 Then
        yawint -= 90
    End If
    If yawint < -90 Then
        yawint += 90
    End If

    Yaw_txt.Text = yawint '<--put this line here will solve your "070" issue

    If Yaw_txt.Text.Length <> 0 Then
        If Yawlbl.Text <> Yaw_txt.Text Then
            Yawlbl.Text = Yaw_txt.Text
        End If
    End If
将主菜单变暗为新主菜单
Dim pitchint作为整数
pitchint=Val(Pitch_txt.Text)'简单方式将过滤掉尾随的非数字输入
如果pitchint>720,则
pitchint-=720
ElseIf pitchint>360则
pitchint-=360
如果结束

Pitch_txt.Text=pitchint'查看单例模式:

确保您从未实例化过多个MainMenu表单实例,然后在需要时引用该表单。您可能需要在更大的范围内实例化它,例如“Main”子对象(或者任何与C#中的公共静态void Main()等效的VB)

编辑:在VB Windows窗体项目中,如果您不愿意解散应用程序框架,您仍然可以从启动窗体实例化任何其他窗体。如果MainMenu是您的启动窗体,那么请确保将MainMenu设置为Form2的所有者。所以它可能看起来像:

Public Class MainMenu

  Public Sub Foo()
    ' This is wherever you instantiate Form2
    Dim frm2 As New Form2()
    ' There are a few ways to declare frm2's owner:
    frm2.Owner = Me
    frm2.Show(Me)
  End Sub
End Class
然后在表格2中:

Public Class Form2
  Private Sub Form2_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim pitchint As Integer
    pitchint = Val(Pitch_txt.Text) 'simple way will filter out trailing non-numerics input
    If pitchint > 720 Then
        pitchint -= 720
    ElseIf pitchint > 360 Then
        pitchint -= 360
    End If

    Pitch_txt.Text = pitchint '<--put this line here will solve your "070" issue

    ' refer to MainMenu as Form2's owner:
    Me.Owner.Pitchlbl.Text = pitchint

    ' Etc...
  End Sub
End Class
公共类表单2
私有子表单2_Load(发送方作为System.Object,e作为System.EventArgs)处理MyBase.Load
Dim pitchint作为整数
pitchint=Val(Pitch_txt.Text)'简单方式将过滤掉尾随的非数字输入
如果pitchint>720,则
pitchint-=720
ElseIf pitchint>360则
pitchint-=360
如果结束

Pitch_txt.Text=pitchint'我的解决方案被错误地描述了,对于回答这个问题的各种可能的方法存在一些混淆,因此我编辑了我的原始帖子,比较和对比了本页详细讨论的三种主要方法

解决方案1:使用VB.NET默认表单实例

将此行放在
Dim main menu之后,作为新的main menu

mainmenu.Show()
您可能有两个主菜单表单。这是因为VB允许您仅通过使用表单的类名来引用表单的静态实例。因此,您可以说,即,
main menu.Property=value
,它将在VB创建的静态实例上运行

尝试删除行
Dim main menu作为新的main menu
。这可能是您所需要做的全部(只要您显示()表单),因为您调用的引用与类名相同

解决方案2:遵循单例设计模式(简化版,无线程安全)

singleton设计模式确保一个类只能有一个实例。将此代码放入主菜单肯定会导致屏幕上出现一些错误

Public Class MainMenu

    ' static (shared) instance of this class
    Private Shared _instance As MainMenu

    ' function which returns the static instance
    ' with lazy initialization (constructor is called once GetInstance is 
    Public Shared Function GetInstance() As MainMenu
        If _instance Is Nothing Then
            _instance = New MainMenu()
        End If
        Return _instance
    End Function

    ' private constructor to restrict instantiation of this class (only allowed in GetInstance)
    Private Sub New()
        ' This call is required by the designer.
        InitializeComponent()
        ' Add any initialization after the InitializeComponent() call.

    End Sub

    ' all the rest of your original MainMenu code here

End Class
修复错误的方法是使用变量保存对MainMenu实例的引用。简单地说,将
mainmenu
替换为类似
myMainMenu
的变量,在使用表单之前,请输入以下内容:

Dim myMainMenu As MainMenu = MainMenu.GetInstance()
myMainMenu.Show()
解决方案3:创建自己的实例

解决方案1解决方案3之间存在差异。在解决方案1中,如果仅使用默认实例,则只有一个表单实例。此解决方案允许您拥有任意数量的实例!你可能不需要这个,但现在

您将再次创建一个名为myMainMenu的MainMenu的新实例,但这次您将直接调用构造函数

Dim myMainMenu As New MainMenu()
myMainMenu.Show()
无论您在哪里以名称
mainmenu
调用表单,请将其替换为
myMainMenu
。我提到过我们称它为myMainMenu而不是mainmenu是因为我们不想使用与类名相同的名称吗?(VB不区分大小写,因此
mainmenu
=
mainmenu
,但由于默认实例,这很容易混淆。编译器使用上下文来确定我们谈论的是类本身还是类的默认实例…)只有在引用解决方案1中的默认静态实例时,使用类名才有效

这个解决方案最吸引人的地方是,您可以同时激活多个MainMenu实例。所以你可以把它放在后面:

Dim myMainMenu2 As New MainMenu()
myMainMenu2.Show()
瞧,你打开了两个主菜单。但你可能不需要两个

摘要

为什么有这么多方法

添加第一种方法是为了吸引VB6程序员访问VB.NET,因为在VB6中就是这样做的!准确地说,它可以在VB6中以这种方式完成,但一些半脑程序员仍然选择使用方法3。但是默认实例方法非常普遍,因为它对于普通程序员来说非常容易使用——特别是那些在VBA中使用它的外行

第二种方法在某些情况下是首选的,但在其他情况下不是。它是单例设计模式的一个简单实现。请查看Douglas Barbie答案中的链接,以获得关于它的合理解释和一些Java示例。它列出了您需要使用它的所有时间的一个很好的摘要-一个记录器,它应该只有一个实例、一个配置加载器、一个工厂或其他实例生成器-这些可能不在您的范围之内,但可能只是想一想Microsoft Office中的打印对话框。一次只需要打开一个打印窗口。这是一个很好的例子。你的代码需要这个吗?遵循该模式允许这种行为,但正如我在示例中所说的,还有一些额外的配置。如果应用程序足够简单,它可能不需要它

第三个是面向对象编程的一个典型示例(一个好的起点是理解OOP;只有这些知识才能为您将来解决类似问题提供工具)。它使用您创建的名为MainMenu的类,并可能使用该类的多个实例(称为Object)。优势
Public Class Form2
    'This will hold a reference to the MainMenu instance
    Private mainMenuForm As MainMenu

    Public Sub New(parent As MainMenu)
        mainMenuForm = parent
    End Sub

    Private Sub SomeMethod()
        mainmenuForm.Pitchlbl.Text = "Some new value"
    End Sub
End Class
Dim frm2 As New Form2(Me)     'Pass the reference to the current MainMenu form to Form2
frm2.Show()