【问题标题】:How to pass a form as the parameter of a function vb.net如何将表单作为函数vb.net的参数传递
【发布时间】:2014-10-22 16:53:42
【问题描述】:

目前在 VB.NET 中,我有两个这样的公共子:

Public Sub addmember1()
    'Stuff
End Sub

Public Sub furtherinfo1()
    'suff
End Sub

我没有包含“'stuff”的代码,因为它很长并且在每个子中完全相同,但是基本原理保持不变。

根据布尔值运行某个子项。就这样……

If add_member = True Then
    addmember1()
ElseIf add_member = False Then
    furtherinfo1()
End If

我将如何使用一个函数来执行与上述相同的过程? (我目前的解决方案有效,但涉及重复同一段代码两次)

我尝试了以下但不成功

Public Function forms(ByVal frm As Windows.Forms.Form)
    'stuff
End Function

然后像这样运行函数...(addmember 和进一步信息是我正在使用的两种形式)

        If add_member = True Then
            forms(addmember)
        ElseIf add_member = False Then
            forms(furtherinfo)
        End If

这里是所有上下文代码的粘贴箱,它是模态的,我想用它来将信息写入 word 文档。第 20-71、76-128、160-164 行就是我要讨论的内容。

http://pastebin.com/xWD0RBuh

【问题讨论】:

  • unsuccessful 表示...?
  • 为什么会有多个子例程“完全相同”的实现?重复使用一个版本不是很有意义吗?
  • ...通过一些破译尝试,我猜他的意思是他正在使用两个不同的表单对象(硬编码)执行相同的代码,所以它并不是真正完全相同(但这是一个猜测)。
  • 它不起作用我收到错误“txtUsername 不是 system.Windows.Forms.form 的成员”
  • 我建议重新表述这个问题,以便不熟悉您项目的人能够理解您想要做什么。

标签: vb.net


【解决方案1】:

您可以将表单对象传递给模块中的 Sub(),如下所示

模块打印

Dim StrToAdd As String
Sub MySub(ByVal frm As Form)
    'The first line is your code
    StrToAdd = "Firstname:  " & addmember.txtName.Text
    'Change it to as below using frm.Controls("controlname").Text
    StrToAdd = "Firstname:  " & frm.Controls("txtName").Text
End Sub

结束模块

【讨论】:

    【解决方案2】:

    http://pastebin.com/xWD0RBuh 查看您的代码后,您似乎有一个包含多个子例程的全局模块。每个子例程都引用了表单实例上的控件(例如文本框)。这意味着每个全局模块子例程都需要访问此表单实例。

    您只复制了应用程序的一部分 - 全局模块,但您没有复制表单定义。我假设您有一个名为 addmember 的表单,但我在示例中没有看到它 - 除了全局模块中的引用。

    不确定您如何使用子例程 - 可能是单击按钮。如果是我,我会创建一个类对象,它的属性包含要传递的数据——要打印的表单上的每个控件都有一个属性。单击按钮后,我将创建类的一个实例并将表单控件中的值复制到类属性中。然后我会将类的实例传递给子例程,并且我会更改子例程以引用类的实例而不是表单的实例。这将提供表单(UI)和行为(打印的子例程)之间的层次抽象。我什至可能会“发疯”并使用界面。

    您的代码是否按原样编译?

    【讨论】:

      【解决方案3】:

      问题是您的两个表单是两个不同的类。即使您为控件命名 同样,您不能仅通过frm.txtUsername 访问它们。

      您可以做的是遍历每个表单的所有控件并按名称找到它们:

      Public Sub DoStuff(frm As Form)
          Dim txtUsername As TextBox = GetControlByName(frm, "txtUsername")
          txtUsername.Text = "Hello World"
      End Sub
      
      Private Function GetControlByName(container As Control, name As String) As Control
          Dim retVal As Control = Nothing
          If Not TryGetControlByName(container, name, retVal) Then Throw New ApplicationException("control not found")
          Return retVal
      End Function
      
      Private Function TryGetControlByName(container As Control, name As String, ByRef ctl As Control) As Boolean
          For Each item As Control In container.Controls
              If item.Name = name Then
                  ctl = item
                  Return True
              End If
      
              'If item is a Container (like GroupBox, Panel) check its children
              If TryGetControlByName(item, name, ctl) Then Return True
          Next
          Return False
      End Function
      

      如果你想变得非常花哨,你可以定义一个带有公共控件的类,并通过一点点填充它们 一点反射魔法。虽然这可能有点矫枉过正:

      Public Sub DoStuff2(frm As Form)
          Dim wrapper As New CommonForm(frm)
          wrapper.txtUsername.Text = "Hello Wolrd"
      End Sub
      
      Public Class CommonForm
          Public Property txtUsername As TextBox
          Public Property txtFoo As TextBox
          Public Property txtBar As TextBox
          'Add more Controls here...
      
          Public Sub New(frm As Form)
              For Each item In Me.GetType().GetProperties()
                  Dim value = GetControlByName(frm, item.Name)
                  item.SetValue(Me, value, Nothing)
              Next
          End Sub
      
          Private Function GetControlByName(container As Control, name As String) As Control
              Dim retVal As Control = Nothing
              If Not TryGetControlByName(container, name, retVal) Then Throw New ApplicationException("control not found")
              Return retVal
          End Function
      
          Private Function TryGetControlByName(container As Control, name As String, ByRef ctl As Control) As Boolean
              For Each item As Control In container.Controls
                  If item.Name = name Then
                      ctl = item
                      Return True
                  End If
      
                  'If item is a Container (like GroupBox, Panel) check its children
                  If TryGetControlByName(item, name, ctl) Then Return True
              Next
              Return False
          End Function
      
      End Class
      

      【讨论】:

        猜你喜欢
        • 2013-10-30
        • 2012-08-15
        • 1970-01-01
        • 2014-06-29
        • 1970-01-01
        • 2014-04-13
        • 2015-09-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多