Fas*_*tAl 6 .net vb.net object winforms
我注意到VB.Net对Winform对象的处理非常讨厌.
这已经破坏了我们几个小时的时间.它只会变得更糟,因为我们有更多的VB6程序员用来做这样的事情,并且自动转换的代码从vb6直接带来了构造.
这是一种可接受的做事方式:
Dim FormInstance as New FormClassName
If FormInstance.ShowDialog() = DialogResult.OK then
TheAnswer = FormInstance.TextBox1.Text
EndIf
Run Code Online (Sandbox Code Playgroud)
但是,它允许这样:
If FormClassName.ShowDialog() = DialogResult.OK then
TheAnswer = FormClassName.TextBox1.Text
EndIf
Run Code Online (Sandbox Code Playgroud)
请记住,属性和方法不是共享的.转换应用程序框架并不重要.似乎在幕后,VB实例化了表单的全局副本,并将此语法重新路由到该全局引用.你可以想象这对现代节目造成的破坏!通常开发人员会把它扔进去或者我们会错过从转换中清除一些模糊的代码(是的,我现在正在寻找这个,所以这有帮助).
我可以做的任何设置导致它抛出错误信息,例如Reference to a non-shared member requires an object reference,像它应该的那样?
我选择了jmoreno的答案,因为他指出了我的罪魁祸首:My.Forms.修复它就像把它放在一个模块中一样简单:
Namespace My.MyProject.MyForms
End Namespace
Run Code Online (Sandbox Code Playgroud)
然后你得到我上面提到的确切错误.就像你应该的那样.如果您需要遗留应用程序(一件好事),那么就不要这样做!我认为Gserg可能只是VB抨击(有趣但没有帮助),但他马上提到了这一切,因为我找到了答案,我们再次对vb不再吮吸,除非你不熟悉它.
请注意,如果您使用应用程序框架,则会在application.designer中收到您不想要的错误.修复:
Protected Overrides Sub OnCreateMainForm()
''//was: Me.MainForm = Global.WindowsApplication2.Form1
Me.MainForm = New Form1
End Sub
Run Code Online (Sandbox Code Playgroud)
希望这对任何不良副作用都是如此!
以上是如此简单以至于我不想提出任何其他建议,但是如果你很好奇,那么这些代码的改进就是(1)添加反射以省略必须在你制作的每个表格中进行硬编码,以及(2)自动制作强制执行(在程序启动时只调用一次该子程序).把它放在一个模块中:
Public Sub FixMyForms()
For Each pi As System.Reflection.PropertyInfo In GetType(My.MyProject.MyForms).GetProperties
Dim obj As Object = pi.GetValue(My.Forms, Nothing)
If TypeOf obj Is Form Then
AddHandler CType(obj, Form).Load, AddressOf Complainer
End If
Next
End Sub
Private Sub Complainer(ByVal sender As Object, ByVal e As System.EventArgs)
MsgBox("WRONG!")
End Sub
Run Code Online (Sandbox Code Playgroud)
不.这种令人困惑的行为是设计上的.
在VB中可以使用一个表单实例而不创建它,这种行为很高兴地使它成为VB.NET.对我来说,这是最糟糕的设计选择之一.
但它确实使遗留项目的转换更容易.它对那些从未知道某个表单可以被明确实例化的人有利.
但是你不需要使用这个技巧,因为你从未在VB6中使用过.在这两种语言中,您都可以使用显式创建的实例,在这种情况下,不会创建默认实例.只要忘记这个"功能"存在,只有在启发他人时才会让它回到你的脑海.
有点。您可以创建一个函数或重写 ShowDialog 来检查 My.Forms 集合以查看当前实例是否在其中以及是否引发异常。没有可用于防止其被使用的设置。
编辑:添加示例代码来说明该概念(使用蜂鸣声而不是异常)。
Shared Function FormIsInMyForms(formName As String, frm As Form)
If formName = "Form1" Then
If frm.Equals(Form1) Then
Return True
Else
Return False
End If
End If
Return False
End Function
Public Overloads Sub ShowDialog()
If FormIsInMyForms("Form1", Me) Then
Beep()
End If
MyBase.ShowDialog()
End Sub
Run Code Online (Sandbox Code Playgroud)
通过反射做同样的事情留给读者作为练习......:)