VB.NET学习笔记:再谈WinForm窗体间相互传值(单值、多值)——属性、委托和事件

在《VB.NET学习笔记:窗体显示及互相传值》一文中,通过默认的窗体实例、保持窗体引用的全局性或在窗体构造函数中把窗体指针作为参数传递,这些方法都是直接操作窗体中的任何控件来读取和改变窗体内的信息。这样会在窗体间大量互相引用各自的成员,造成了彼此之间存在着很大的耦合性,非常不利于窗体模块间的独立,破坏了类型封装性的原则。在.NET下,还为我们提供了另外一种强大的机制来实现窗体通信,这就是委托。

属性与委托实现窗体间相互传值

新一个Windows窗体应用程序,包含MainFrm和ChildFrm共2个窗体,还有一个Middle模块,在这两个窗体里均拖入一个文本框TextBox控件和一个Button控件。
MainFrm窗体代码:

Public Class MainFrm
    Private f As New ChildFrm
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        f.ReceiveOrSendMessage = TextBox1.Text
    End Sub

    Private Sub MainFrm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        f.action = Sub(msg)
                       TextBox1.Text = msg
                   End Sub
        f.Show()
    End Sub
End Class

ChildFrm窗体代码:

Public Class ChildFrm
    '属性传值
    Public Property ReceiveOrSendMessage() As String
        Get
            Return TextBox1.Text
        End Get
        Set(ByVal Value As String)
            TextBox1.Text = Value
        End Set
    End Property

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        action.Invoke(ReceiveOrSendMessage)
    End Sub
End Class

Middle模块代码:

Module Middle
    '委托传值
    Public action As Action(Of String)
End Module

MainFrm窗体有ChildFrm窗体实例,可以直接访问ChildFrm实例的ReceiveOrSendMessage属性向ChildFrm窗体传值。通过ReceiveOrSendMessage属性来访问ChildFrm与直接访问 ChildFrm非常相似。然而,这种间接的窗体访问方式实现了更高的抽象性。哪怕你不知道ChildFrm 中控件的任何细节 (比如:窗体中是否包含 textbox 控件) ,也能与ChildFrm交换数据;你所要做的只是读取或设置ReceiveOrSendMessage 属性值而已。有了这种抽象,你就能在修改 ChildFrm 的实现时不影响项目中的其它代码,因而大大简化了整个项目代码的维护。
ChildFrm窗体中没有MainFrm窗体,不能直接访问MainFrm窗体实例,所以使用委托实现向MainFrm窗体传值。通过委托,MainFrm和ChildFrm都与委托通信,它们之间除了参数的耦合外,已不再引用彼此的内部成员,这样就显得更加独立了。
测试效果如图:
VB.NET学习笔记:再谈WinForm窗体间相互传值(单值、多值)——属性、委托和事件_第1张图片
当然了,网上也有人说通过属性公开还是会导致父窗体与子窗体耦合过于紧密,建议全部封装到一个中间类 Middle类中。具体可以参考《窗体间传递复杂数据》一文。

使用事件参数实现窗体间相互传值

新一个Windows窗体应用程序,包含MainFrm和ChildFrm共2个窗体,还有一个继承自EventArgs的消息类FrmEventArgs和一个中间类Middle类,在这两个窗体里均拖入一个文本框TextBox控件和一个Button控件。

1、FrmEventArgs类代码

Public Class FrmEventArgs
    Inherits EventArgs
    Public Property ReceiveOrSendMessage() As String = String.Empty
End Class

2、Middle类代码

Public Class Middle
    Public Shared Event MainSendMessage As EventHandler(Of FrmEventArgs)
    Public Shared Event ChildSendMessage As EventHandler(Of FrmEventArgs)

    Public Shared Sub OnMainTextBoxChange(sender As Object, e As FrmEventArgs)
        RaiseEvent MainSendMessage(sender, e)
    End Sub

    Public Shared Sub OnChildTextBoxChange(sender As Object, e As FrmEventArgs)
        RaiseEvent ChildSendMessage(sender, e)
    End Sub
End Class

3、MainFrm窗体代码

Public Class MainFrm
    Private f As New ChildFrm
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim args As New FrmEventArgs
        args.ReceiveOrSendMessage = TextBox1.Text
        Middle.OnChildTextBoxChange(Nothing, args)
    End Sub

    Private Sub MainFrm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        AddHandler Middle.MainSendMessage, AddressOf DoMainMethod
        AddHandler Middle.ChildSendMessage, AddressOf f.DoChildMethod
        f.Show()
    End Sub

    Private Sub DoMainMethod(sender As Object, e As FrmEventArgs)
        TextBox1.Text = e.ReceiveOrSendMessage
    End Sub
End Class

4、ChildFrm窗体代码

Public Class ChildFrm
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim args As New FrmEventArgs
        args.ReceiveOrSendMessage = TextBox1.Text
        Middle.OnMainTextBoxChange(Nothing, args)
    End Sub

    Public Sub DoChildMethod(sender As Object, e As FrmEventArgs)
        TextBox1.Text = e.ReceiveOrSendMessage
    End Sub
End Class

多值传递

很简单,只需要把委托或事件参数设置为一个数组或其他可以储存多值的对象中即可。
窗体传值的方式多种多样,还可以通过控件的Tag属性,有仅父向子传值、子向父传值或双向传值,本文仅探讨双向传值。

你可能感兴趣的:(VB.NET学习笔记,VB.NET委托与线程)