我注意到VB.Net对Winform对象的处理非常讨厌.
这已经破坏了我们几个小时的时间.它只会变得更糟,因为我们有更多的VB6程序员用来做这样的事情,并且自动转换的代码从vb6直接带来了构造.
这是一种可接受的做事方式:
Dim FormInstance as New FormClassName If FormInstance.ShowDialog() = DialogResult.OK then TheAnswer = FormInstance.TextBox1.Text EndIf
但是,它允许这样:
If FormClassName.ShowDialog() = DialogResult.OK then TheAnswer = FormClassName.TextBox1.Text EndIf
请记住,属性和方法不是共享的.转换应用程序框架并不重要.似乎在幕后,VB实例化了表单的全局副本,并将此语法重新路由到该全局引用.你可以想象这对现代节目造成的破坏!通常开发人员会把它扔进去或者我们会错过从转换中清除一些模糊的代码(是的,我现在正在寻找这个,所以这有帮助).
我可以做出任何设置来引发错误消息,例如,引用非共享成员需要一个对象引用,就像它应该的那样?
这是解决方案:
我选择了jmoreno的答案,因为他指出了我的罪魁祸首:My.Forms.修复它就像把它放在一个模块中一样简单:
Namespace My.MyProject.MyForms End Namespace
然后你得到我上面提到的确切错误.就像你应该的那样.如果您需要遗留应用程序(一件好事),那么就不要这样做!我认为Gserg可能只是VB抨击(有趣但没有帮助),但他马上提到了这一切,因为我找到了答案,我们再次对vb不再吮吸,除非你不熟悉它.
请注意,如果您使用应用程序框架,则会在application.designer中收到您不想要的错误.修复:
Protected Overrides Sub OnCreateMainForm() ''//was: Me.MainForm = Global.WindowsApplication2.Form1 Me.MainForm = New Form1 End Sub
希望这对任何不良副作用都是如此!
JMoreno的反思等
以上是如此简单以至于我不想提出任何其他建议,但是如果你很好奇,那么这些代码的改进就是(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
八九不离十.您可以创建一个函数或覆盖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
通过反思做同样的事情留给读者练习……