导致这种 VB.NET 允许的类似 VB6 的气味发生错误:WinFormType.InstanceProp=Value [DISABLE My.Forms] [英] Cause this VB6-like smell, which VB.NET allows, to error instead: WinFormType.InstanceProp=Value [DISABLE My.Forms]

查看:12
本文介绍了导致这种 VB.NET 允许的类似 VB6 的气味发生错误:WinFormType.InstanceProp=Value [DISABLE My.Forms]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到 VB.Net 对 Winform 对象的处理非常令人讨厌.

I have notice something very obnoxious with VB.Net's treatment of Winform objects.

这浪费了我们几个小时的时间.随着我们有更多的 VB6 程序员习惯于做这样的事情,并且自动转换的代码直接从 vb6 中引入结构,情况只会变得更糟.

This has trashed several hours of our time. It will only get worse as we have more of our VB6 programmers that are used to doing things like this, and autoconverted code which brings the construct straight over from vb6.

这是一种可以接受的做事方式:

Here is an acceptable way to do things:

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 实例化了表单的全局副本,并将此语法重新路由到该全局引用.您可以想象这对现代程序造成的破坏!通常,开发人员会将它扔进去,否则我们会错过清理转换过程中一些晦涩难懂的代码(是的,我现在正在寻找它,因此会有所帮助).

Bear in mind, the properties and methods are not Shared. Turning of Application Framework doesn't matter. It seems that behind the scenes, VB instantiates a global copy of the form, and re-routes this syntax to that global reference. You can imagine the havoc this wreaks on a modern program! Often a developer will throw it in or we'll miss cleaning up some obscure code from conversion (yes, I am looking for this now, so that helps).

我可以进行任何设置以导致抛出错误消息,例如,对非共享成员的引用需要对象引用,就像它应该的那样?

Any setting I can make to cause this to throw an error message, e.g., Reference to a non-shared member requires an object reference, like it ought to?

我选择jmoreno的答案是因为他为我指出了罪魁祸首:My.Forms.修复它就像把它放在一个模块中一样简单:

I chose to select the answer of jmoreno because he pointed out the culprit for me: My.Forms. Fixing it was as easy as putting this in a module:

Namespace My.MyProject.MyForms
End Namespace

然后你会得到我上面提到的确切错误.就像你应该的那样.如果您需要旧版应用程序(一件好事),那么不要这样做!我认为 Gserg 可能只是在抨击 VB(有趣但无济于事),但他马上提到了所有这些,自从我找到答案后,我们再次对 vb 没有吸引力,除非您不熟悉它.

Then you get the exact error I mentioned above. Just like you should. If you need that for legacy apps (a good thing), then don't do this! I thought Gserg might just be VB bashing (fun but not helpful) but he mentioned all this right away, and since I found the answer, there we're good again about vb not sucking unless you are just unfamiliar with it.

请注意,如果您使用应用程序框架,您将在 application.designer 中收到您不想要的错误.修复:

Note if you use the application framework you'll get an error you don't want in application.designer. The fix:

    Protected Overrides Sub OnCreateMainForm()
        ''//was: Me.MainForm = Global.WindowsApplication2.Form1
        Me.MainForm = New Form1
    End Sub

希望对任何不良副作用都如此!

Hopefully that would be it for any bad side effects!

以上内容非常简单,我不想提出任何其他建议,但是如果您感到好奇,这里有对该代码的改进,以 (1) 添加反射以省略必须在您制作的每种形式中进行硬编码和 (2)使其自动执行(在程序启动时只需调用一次此子程序).把它放在一个模块中:

The above is so simple that I'd hate to suggest anything else, but if you are curious, here are improvements on that code to (1) add reflection to omit having to hardcode in each form you make and (2) make it automatically enforcing (with just one call to this sub at program startup). Just put this in a module:

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

推荐答案

Sorta.您可以创建一个函数或覆盖 ShowDialog 来检查 My.Forms 集合以查看当前实例是否在其中以及是否引发异常.没有一个设置可以用来阻止它被使用.

Sorta. You could create a function or override ShowDialog that checks the My.Forms collection to see if the current instance is in it and if it is thrown an exception. There's not a setting that can be used to prevent it from being used.

添加说明该概念的示例代码(使用哔声而不是异常).

adding sample code illustrating the concept (using a beep instead of an exception).

    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

通过反射做同样的事情留给读者作为练习...... :)

Doing the same thing via reflection is left as an exercise for the reader... :)

这篇关于导致这种 VB.NET 允许的类似 VB6 的气味发生错误:WinFormType.InstanceProp=Value [DISABLE My.Forms]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆