在Visual Basic 2008 Express中,我想引用一个表单。但是,当我输入Dim mainmenu as New MainMenu
时,会创建一个新实例。当我想使用表单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
这将创建表单主菜单的新实例。然后,当我插入行mainmenu.Yawlbl.Text = yawint
和mainmenu.Pitchlbl.Text = pitchint
时,没有任何反应。我没有得到任何错误。请帮忙。提前谢谢。
答案 0 :(得分:2)
我的解决方案被错误描述,并且对于回答这个问题的各种可能方法存在一些混淆,因此我编辑了我的原始帖子,以比较和对比本页详细讨论的三种主要方法。
解决方案1:使用VB.NET默认表单实例
将此行放在Dim mainmenu As New MainMenu
之后:
mainmenu.Show()
您可能会有两个MainMenu表单。这是因为VB允许您仅使用其类名引用表单的静态实例。所以你可以说ie MainMenu.Property = value
并且它将在VB创建的静态实例上运行。
尝试删除行Dim mainmenu As New MainMenu
。这可能是您需要做的所有事情(只要您显示表单),因为您调用的引用与类名相同。
解决方案2:遵循Singleton设计模式(简化版,无线程安全)
单例设计模式确保只能有一个类的实例。将此代码放入MainMenu肯定会导致屏幕上出现一些错误。
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
,但由于默认实例,这很容易让人困惑。编译器使用上下文来确定我们是在讨论类本身还是类的默认实例...)使用classname仅在引用默认静态实例时有效,如解决方案1 中那样。
此解决方案的吸引人之处在于您可以同时使多个MainMenu实例处于活动状态。所以你可以把它放在:
之后Dim myMainMenu2 As New MainMenu()
myMainMenu2.Show()
瞧,你有两个MainMenu打开。但你可能不需要两个!
<强>摘要强>
为什么有那么多方法?
嗯,第一种方法是为了吸引VB6程序员加入VB.NET,因为这是在VB6中完成的!准确地说,可以在VB6中以这种方式完成,但是一些半脑的程序员仍然选择遵循方法3.但是默认的实例方法是如此广泛,因为它对于偶然来说非常容易程序员使用 - 特别是那些在VBA内使用它的外行!
在某些情况下,第二种方法是首选,但在其他情况下则不是。它是Singleton设计模式的简单实现。查看Douglas Barbie的答案中的链接,以获得对它的正确解释和Java中的一些示例。它列出了你需要使用它的所有时间的一个很好的总结 - 一个只应该有一次实例的记录器,一个配置加载器,一个工厂或其他实例生成器 - 这些可能超出了你的范围,但可能只是考虑一下Microsoft Office中的“打印”对话框。一次只需打开一个打印窗口。这是一个很好的例子。你的代码是否需要这个?遵循该模式允许此行为,但是我在示例中添加了一些其他配置。如果应用程序足够简单,它可能不需要它。
第三个是面向对象编程的典型例子(一个好的起点是理解OOP;这个知识本身应该为你提供解决这类问题的工具)。它使用您创建的名为MainMenu的类,并且可能使用多个类的实例,称为 objects 。这样做的一个优点是,您可以拥有同一个类的两个对象实例,但这些对象具有不同值的属性。考虑两个类Car
的实例,一个具有Car.Make = "Ford"
,另一个Car.Make = "Chevy"
。两辆车,但它们的属性值不同。这与前两个不同之处仅在于您可以拥有多个实例。如果我们想获得技术,您可以合并解决方案1和3并使用默认实例并创建自己的实例,但几乎所有讨论它的人都会对此进行警告(Google“VB.NET form default instance”了解更多信息)那件事。)
最后,如果你是小规模的编码,那就是你可靠的工作。
答案 1 :(得分:1)
查看单身人士模式:http://www.oodesign.com/singleton-pattern.html
确保您永远不会实例化MainMenu表单的多个实例,然后随时引用该表单。您可能必须在更大的范围内实例化它,例如“Main”Sub(或者VB等效于C#中的public static void Main())。
编辑:在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
然后在Form2中:
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 :(得分:0)
您需要将对MainMenu表单的引用传递给Form2。所以Form2可能看起来像这样(代码仅用于说明目的。不完整):
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
然后在您需要显示Form2的MainMenu表单中:
Dim frm2 As New Form2(Me) 'Pass the reference to the current MainMenu form to Form2
frm2.Show()