因为这VB6般的气味,这VB.NET允许,到错误,而不是:WinFormType.InstanceProp =值[无效My.Forms] [英] Cause this VB6-like smell, which VB.NET allows, to error instead: WinFormType.InstanceProp=Value [DISABLE My.Forms]

查看:192
本文介绍了因为这VB6般的气味,这VB.NET允许,到错误,而不是:WinFormType.InstanceProp =值[无效My.Forms]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经注意到一些很讨厌的用VB.Net的治疗WinForm的对象。

这已经丢弃几个小时我们的时间。它只会变得更糟,因为我们有我们更多的VB6程序员用来做这样的事情,并autoconverted code从VB6带来的结构直冲了过来。

下面是一个可以接受的方式做的事情:

 暗淡FormInstance作为新FormClassName
如果FormInstance.ShowDialog()= DialogResult.OK然后
    TheAnswer = FormInstance.TextBox1.Text
ENDIF
 

但是,它允许这样的:

 如果FormClassName.ShowDialog()= DialogResult.OK然后
    TheAnswer = FormClassName.TextBox1.Text
ENDIF
 

记住,属性和方法不能共享。谈到应用程序框架的无所谓。看来,在幕后,VB实例形式的全局副本,并重新路由,该语法来全球基准。你可以想象这造成十分一座现代化计划的破坏!通常,开发商会扔在,否则我们就会错过清理从转换一些模糊的code(是的,我找的这个现在,这样有利于)。

任何设置,我可以做,使这个抛出一个错误信息,如引用到非共享成员需要一个对象引用,喜欢它应该?

这里的解决方案:

我选择选择jmoreno的答案,因为他指出罪魁祸首对我来说: My.Forms 。修复这是因为把这个模块中的一样简单:

 命名空间My.MyProject.MyForms
最终命名空间
 

然后你得到我上面提到的确切的错误。就像你应该。如果需要,对于传统应用程序(一件好事),那么不这样做!我想Gserg可能只是VB扑(有趣,但没有帮助),但他提到的这一切的时候了,因为我找到了答案,但我们和好如初约VB不吸,除非你只是不熟悉它。

请注意,如果你使用的应用程序框架,你会得到你不想在application.designer错误。解决方法:

 受保护的覆盖子OnCreateMainForm()
        ''//是:Me.MainForm = Global.WindowsApplication2.Form1
        Me.MainForm =新Form1中
    结束小组
 

我希望这将是它的任何不良副作用!

JMoreno的反思等。

以上是如此简单,我讨厌建议别的,但如果你是好奇,这里有改进上code:(1)增加反射省略不必硬code在每个形成你做出和(2)使自动执行(以在程序启动时只需一个电话到这个分)。只要把这个模块中的:

 公用Sub FixMyForms()
    对于每一个PI作为System.Reflection.PropertyInfo在的GetType(My.MyProject.MyForms).GetProperties
        昏暗的OBJ作为对象= pi.GetValue(My.Forms,为Nothing)
        如果TypeOf运算obj是表格然后
            AddHandler的CTYPE(OBJ,表格).Load,AddressOf抱怨
        结束如果
    下一个
结束小组

私人小组抱怨(BYVAL发件人为对象,BYVALË作为System.EventArgs)
    MSGBOX(错!)
结束小组
 

解决方案

八九不离十。你可以创建一个函数或覆盖的ShowDialog来检查My.Forms集合,看看目前的情况是在它,如果它被抛出的异常。这里没有可以用来prevent它被使用的设置。

编辑:加样code说明概念(用异常的嘟嘟声代替)

 共享功能FormIsInMyForms(窗体名称作为字符串,FRM作为表)
        如果窗体名称=Form1的那
            如果frm.Equals(Form1中)然后
                返回TRUE
            其他
                返回False
            结束如果
        结束如果
        返回False

    端功能

    公共重载子的ShowDialog()

        如果FormIsInMyForms(Form1的,我的)然后
            嘟()
        结束如果

        MyBase.ShowDialog()
    结束小组
 

这样通过反射一样的东西是留给作为练习读者...:)

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

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

However, it allows this:

If FormClassName.ShowDialog() = DialogResult.OK then
    TheAnswer = FormClassName.TextBox1.Text
EndIf

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?

Here's the solution:

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

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.

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!

JMoreno's reflection, etc.

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. 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.

EDIT: 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... :)

这篇关于因为这VB6般的气味,这VB.NET允许,到错误,而不是:WinFormType.InstanceProp =值[无效My.Forms]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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