通过传递变量表单名称来启动表单的副本 [英] initiating copies of a form by passing a variable form name
问题描述
我正在学习VB,我试图以两种方式从第二种形式创建一个表单。第一个,通过一个被调用的子并检查表单是否已经存在,如果不存在,则创建一个,但如果已经存在,则不创建一个。这是有效的。
在第二个,我试图做同样的事情,但这一次,传递要打开的表单的名称。如果我声明表单的名称(frm3为New Form2),则子工作但会打开许多实例。如果我没有声明它,我会收到一个错误,我应该声明它。
我错过了没有传递表单的sub正常工作(在btn_click上只创建一个表单,除非表单不存在)而另一个创建多个btn_click活动上的表格?
感谢您的耐心等待!
I am learning VB and I tried to create a form from a second form in 2 ways. The first, by a sub that is called and checks to see if the form is already there, creates one if it isn't, but doesn't make a new one if there is one there already. This works.
In the second, I am trying to do the same, but this time, passing the name of the form to be opened. If I declare the name of the form (frm3 as New Form2), the sub works but opens many instances. If I don't declare it, I get an error that I should have declared it.
What am I missing that the sub without passing the form works correctly (creates only a single form on btn_click unless the form doesn't exist) while the other creates multiple forms on the btn_click event?
Thanks for being patient!
Dim frm2 As Form2
Dim frmName As Form2
Private Sub InitForm()
'rem if form not created already, then show it; If already there, do nothing
If frm2 Is Nothing OrElse frm2.IsDisposed = True Then
frm2 = New Form2
End If
'rem if invisible, show the NEW frm2 form
If frm2.Visible = False Then
frm2.Show()
End If
End Sub
Private Sub btnShowForm2_Click(sender As Object, e As EventArgs) Handles btnShowForm2.Click
'rem use InitForm so initialization of form2 code not repeated; shows the form
InitForm()
End Sub
'rem Wanted to make same Sub as InitForm, but with a form object passed:
Private Sub InitFormPassObj(frmName) rem As Form2)
'rem is form not created already, then show it; If already there, do nothing
If frmName Is Nothing OrElse frmName.IsDisposed = True Then
frmName = New Form2
End If
'rem if invisible, show the NEW frm2 form
If frmName.Visible = False Then
frmName.Show()
End If
End Sub
Private Sub btnShowFrm2ObjectPass_Click(sender As Object, e As EventArgs) Handles btnShowFrm2ObjectPass.Click
Dim frm2 As New Form2
InitFormPassObj(frm2)
frm2.SayHello(txtName.Text)
End Sub
Private Sub btnSayHello_Click(sender As Object, e As EventArgs) Handles btnSayHello.Click
'rem Say Hello is via Public Property in Form2 called Sub SayHello, which accepts a string
InitForm()
'rem SayHello is PUBLIC on Frm2
frm2.SayHello(txtName.Text)
End Sub
End Class
推荐答案
在编程中没有打开表单这样的概念;你只能关闭一个表格:-)
你没有真正传递表单名称,这没有任何意义。你的frmName
是对Form2
类实例的引用(永远不要使用这样的名字;使用重构引擎来改变每个自动生成的名称,并避免自己给出坏名称。)
你做的事情原则上没什么意义。至少你的frmName
和InitForm
都应该是静态的(共享的)。没有它,对于Form2
的每个实例,你将有单独的frmName
。显然,您几乎不了解类型,实例和实例成员(与静态相比)。你需要学习它。
您可能正在尝试将 factory 和 singleton 模式组合在一起,或者只使用其中一个。你做错了。实际上,你可以拥有像你一样的工厂方法,但它应该是某个工厂类的方法或表单类的静态方法,您可以使用它而不是公共/内部构造函数(然后你最好把所有构造函数都设为私有)。如果您需要单身功能,请阅读: https://en.wikipedia.org/wiki/Singleton_pattern [ ^ ]。
我看到很多不好的单例实现。这是正确的: http://csharpindepth.com/Articles/General/Singleton.aspx [ ^ ]。
另请参阅: https://en.wikipedia.org/wiki/Factory_ %28object-oriented_programming%29#VB.NET [ ^ ]。
现在,对于一个侧面建议:我建议您继续进行UI开发,以及其他作为高级或更高级的主题。首先,使用一些简单的仅限控制台的应用程序,对类,实例和OOP充满信心。
-SA
There is no such concept as "open a form" in programming; you can only close a form :-)
You don't really pass the form name, which would not make any sense. YourfrmName
is a reference to an instance ofForm2
class (never ever use names like that; use refactoring engine to change each and every auto-generated names and avoid giving bad names yourself).
What you do makes little sense in principle. At least both yourfrmName
andInitForm
should be static (shared). Without it, you would have separatefrmName
for each instance ofForm2
. Apparently, you have little understanding of types, instances and instance members (vs static). You need to learn it.
It's possible that you are trying to combine factory and singleton patterns, or use just one of them. You are doing it wrong. Indeed, you can have a factory method like yours, but it should either be a method of some "factory" class or a static method of the form class, which you could use instead of public/internal constructor (and then you should better make all constructors private). If you need a singleton feature, read this: https://en.wikipedia.org/wiki/Singleton_pattern[^].
I saw many bad singleton implementations. This is a right one: http://csharpindepth.com/Articles/General/Singleton.aspx[^].
See also: https://en.wikipedia.org/wiki/Factory_%28object-oriented_programming%29#VB.NET[^].
Now, for a side advice: I would recommend you to hold on UI development, as well as other as advanced or more advanced topics. First, get confident with classes, instances and OOP, using perhaps some simple console-only applications.
—SA
谢谢,谢尔盖。我只是想做一个练习,学习如何从另一个表单调用一个表单,改变我的方式。这只是一个爱好,所以你们所有的程序员都是安全的 - 至少对我来说是这样!
Thanks, Sergey. I was just trying to do an exercise to learn how to call one form from another, varying the way I did it. This is only a hobby so all you programmers are safe- at least from me!
这篇关于通过传递变量表单名称来启动表单的副本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!