【问题标题】:VB6 to VB.Net Conversion problems - Name 'Forms'is not declaredVB6 到 VB.Net 的转换问题 - 未声明名称“表单”
【发布时间】:2024-01-19 08:27:02
【问题描述】:

在将 VB6 代码转换为 VB.NET 时,我遇到了几个问题。我将在这里特别处理一个。

VB6原代码为:

Public Sub dynForm(sFormName As String, loadingForm As Form, Optional resizeMe As Boolean = True)
On Error GoTo ErrHandler
    'Used to dynamically open a form based on its name.

    Dim oForm As Form

    'Add a Form to the collection
    Set oForm = Forms.Add(sFormName)

    'Load the Form
    Load oForm
    If resizeMe Then
        setFrmSize oForm
    End If
    centerForm oForm
    'Show The Form
    oForm.Show 1, loadingForm

    If oForm Is Nothing Then Exit Sub
    Set oForm = Nothing

    Exit Sub
ErrHandler:

    logError Err.Description & vbCrLf & "sFrm:" & sFormName & " not found!",       Err.Number, "common.dynForm", ErrorMsg
End Sub

转换过程产生以下结果(我缩短了转换 cmets,它指的是不再有效的链接):

    Public Sub dynForm(ByRef sFormName As String, ByRef loadingForm As System.Windows.Forms.Form, Optional ByRef resizeMe As Boolean = True)
    On Error GoTo ErrHandler
    'Used to dynamically open a form based on its name.

    Dim oForm As System.Windows.Forms.Form

    'Add a Form to the collection
    'UPGRADE_ISSUE: Forms method Forms.Add was not upgraded. 
    oForm = Forms.Add(sFormName)


    'Load the Form
    'UPGRADE_ISSUE: Load statement is not supported. 
    Load(oForm)
    If resizeMe Then
        setFrmSize(oForm)
    End If
    centerForm(oForm)
    'Show The Form
    VB6.ShowForm(oForm, 1, loadingForm)

    If oForm Is Nothing Then Exit Sub
    'UPGRADE_NOTE: Object oForm may not be destroyed until it is garbage collected. 
    oForm = Nothing

    Exit Sub
ErrHandler: 

    logError(Err.Description & vbCrLf & "sFrm:" & sFormName & " not found!", Err.Number, "common.dynForm", ErrorType.ErrorMsg)
    End Sub

返回以下错误:
名称“表格”未声明。 未声明名称“Load”。

我刚刚注释掉了 Load 语句。但事实证明,将表格添加到集合中是一个更难破解的问题。

我尝试了几种变体:

    oForm = System.Windows.Forms.Form.Add(sFormName)

返回错误:'Add' 不是 'System.Windows.Forms.Form' 的成员

    oForm = System.Windows.Forms.Form.AddOwnedForm(sFormName)

返回错误:对非共享成员的引用需要对象引用。

    oForm = My.Forms.Add(sFormName)

返回错误:'Add' 不是 'RSC_Reports.My.MyProject.MyForms' 的成员。

如何获取作为参数传递的表单名称添加到集合中?

【问题讨论】:

  • 您需要为此创建一个 FormsCollection 类。检查此链接 --> support.microsoft.com/kb/308537
  • 您根本不需要Forms 集合。
  • 您的转换器在应该使用 ByVal 时却经常使用 ByRef

标签: vb.net vb6 vb6-migration


【解决方案1】:

VB6 代码正在使用类名创建表单的新实例。 VB.Net 的方法是反射。

尝试使用此代码from here 进行编辑以使其不区分大小写。

Imports System 
Imports System.Windows.Forms 
Imports System.Reflection 

Public Class ObjectFinder 

Public Shared Function CreateObjectInstance(ByVal objectName As String) As Object 
  ' Creates and returns an instance of any object in the assembly by its type name. 

  Dim obj As Object 

  Try 

    If objectName.LastIndexOf(".") = -1 Then 
      'Appends the root namespace if not specified. 

      objectName = [Assembly].GetEntryAssembly.GetName.Name & "." & objectName 

    End If 

    obj = [Assembly].GetEntryAssembly.CreateInstance(objectName, True) 

  Catch ex As Exception 

    obj = Nothing 

  End Try 

  Return obj 

End Function 

Public Shared Function CreateForm(ByVal formName As String) As Form
  ' Return the instance of the form by specifying its name.
  Return DirectCast(CreateObjectInstance(formName), Form)
EndFunction

然后替换你的行。

oForm = Forms.Add(sFormName) 

有了这条线

oForm = ObjectFinder.CreateForm(sFormName)

【讨论】:

  • @Zac 感谢您的编辑!这让我意识到我省略了从原始来源复制部分代码。我现在已将缺少的例程 CreateForm 复制到我的答案中,并将代码改回调用 CreateForm。
  • @MarkJ 提出的代码是正确的,但我仍然有 CreateInstance 调用返回的Nothing 值。只有一个参数的 CreateInstance 区分大小写;我不得不改用CreateInstance(objectName, True),这会激活不区分大小写,因为我使用了错误的驼峰式字符串作为表单名称。
  • 我开始自己更正您的代码,但我取消了所有,因为区分大小写的版本更精确:我不知道如果有两个名称相同但大小写不同的表单会发生什么(实际上我不知道这是否可能)。反正GG