对于大多数可视化的信息系统而言,经常遇到多个窗体交互的现象,其中又以子窗体和父窗体交互居多,刚刚做了一个项目,遇到了很多这种现象,又从网上收集了一些这方面的知识,现在总结一下,做个备份。
信息系统无非是信息获取、后台处理、显示的过程。子窗体和父窗体的交互大多是显示的需要。如果把子窗体和父窗体作为两个对象的话,他们之间的相互操作有几个关键点要理清楚:①操作对象和被操作对象;②触发时点和触发事件;③被操作对象的操作。这其中第二点最为关键,关于怎样触发事件、传递消息和接收消息有很多方法,这是我们要讨论的重点。父窗体操作子窗体是比较简单的,通常子窗体都是父窗体类的一个对象,父窗体想操作子窗体,只需要在触发事件中调用子窗体对象中已暴露的接口,想让子窗体做什么,只需要在接口中实现就可以了。
代码示例如下(VB.net,自动生成代码略去,以下同):
Code
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormParentClass FormParent
2![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
Inherits System.Windows.Forms.Form
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Dim obFormChild As New FormChild
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
obFormChild.DoAction()
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
End Sub
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
End Class
14![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormChildClass FormChild
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
Inherits System.Windows.Forms.Form
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Function DoAction()Function DoAction() As Boolean
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
'添加动作内容
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
End Function
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
End Class
26
下面重点说明子窗体如何操作父窗体的几种方法。
1. 将父窗体实例传递给子窗体作为自己的对象。这个方法等于把父窗体操作子窗体倒过来。但是父窗体一般承载的信息比较多,而且一般不止一个子窗体,这样做容易造成对象的混乱,而且影响类自己的封闭性,效率方面不知道有没有影响(笔者学识尚浅,请高人指教),但是总觉得不优雅,呵呵。
Code1
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormParentClass FormParent
2![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
Inherits System.Windows.Forms.Form
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Dim obFormChild As New FormChild
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub FormParent_Load()Sub FormParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
obFormChild.Show()
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
obFormChild.setParam(Me)
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
End Sub
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Function DoAction()Function DoAction() As Boolean
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
'添加动作内容
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
End Function
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
End Class
22![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormChildClass FormChild
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
Inherits System.Windows.Forms.Form
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
Private obFormParent As FormParent
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub setParam()Sub setParam(ByRef obFormParam As FormParent)
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
Me.obFormParent = obFormParam
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
End Sub
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
36![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
obFormParent.DoAction()
38![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
End Sub
40![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
End Class
42
2. 将父窗体的控件对象传递给子窗体作为自己的对象。这个方法与1类似,优缺点也相似,但是影响的范围小,同时调用的范围也受限制,只能子窗体只能操作传递过来的对象。
Code2
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormParentClass FormParent
2![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
Inherits System.Windows.Forms.Form
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Dim obFormChild As New FormChild
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub FormParent_Load()Sub FormParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9
obFormChild.Show()
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
obFormChild.setParam(Me.Label1)
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
End Sub
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
End Class
16![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormChildClass FormChild
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
Inherits System.Windows.Forms.Form
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21
Private obControlParent As Label
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub setParam()Sub setParam(ByRef obControlParam As Label)
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
Me.obControlParent = obControlParam
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
End Sub
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
obControlParent.Text = "child calls parents"
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
End Sub
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
End Class
36
3. 将父窗体或父窗体的控件传递给第三方对象,子窗体操作第三方对象。这个方法能够实现显示和逻辑处理的分离,类之间的调用关系虽然复杂了一层,但是线路更加清晰了。需要注意的是,这个时候需要父窗体把一部分传递给逻辑对象,再把逻辑对象也传递给子窗体。举个例子:老爷派一个仆人带着钱给少爷买东西,少爷想买啥,仆人就给买给他。这样,老爷就不用管了,但是仆人的权力就大了。而前面的方法全都是老爷和少爷之间的互动。
Code3
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormParentClass FormParent
2![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
Inherits System.Windows.Forms.Form
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Dim obFormChild As New FormChild
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
Dim obLogic As Logic
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub FormParent_Load()Sub FormParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
obLogic = New Logic(Me.Label1)
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
obFormChild.Show()
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
obFormChild.setParam(Me.obLogic)
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
End Sub
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
End Class
20![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormChildClass FormChild
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
Inherits System.Windows.Forms.Form
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
Private obLogic As Logic
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub setParam()Sub setParam(ByRef obLogicParam As Logic)
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
Me.obLogic = obLogicParam
30![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
31
End Sub
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
obLogic.DoAction()
36![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37
End Sub
38![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
End Class
40![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
41![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class LogicClass Logic
42![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43
Private obLabel As Label
44![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub New()Sub New(ByRef obLabelParam As Label)
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
Me.obLabel = obLabelParam
48![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
49
End Sub
50![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
51![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub DoAction()Sub DoAction()
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53
obLabel.Text = "child calls perent with logic"
54![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
55
End Sub
56![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
57
End Class
58
4. 通过第三方逻辑对象进行监控和通信。与3的方法相同部分是需要将逻辑对象传递给子窗体,不同的是需要把父窗体的方法与逻辑类的方法绑定,子窗体通过触发逻辑类的方法来触发父窗体的方法。还是刚才的例子,这次老爷发现仆人吃回扣,于是钱自己管,少爷想买什么,就让仆人告诉老爷,老爷自己买好了给少爷。此方法的好处就是父窗体只需要逻辑类做一个中间的通信兵,动作实现还是自己做,保持了类的封闭性。这个方法是同事提供的,我理解的还不是很深,大体结构如此。
Code4
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormParentClass FormParent
2![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
3
Inherits System.Windows.Forms.Form
4![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
5
Dim obFormChild As New FormChild
6![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
7
Dim obLogic As New Logic
8![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub FormParent_Load()Sub FormParent_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
10![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
11
'定義事件
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
AddHandler obLogic.PassInf4Parent, AddressOf DoAction
14![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
15
obFormChild.setParam(obLogic)
16![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
17
obFormChild.Show()
18![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
19
End Sub
20![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
21![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub DoAction()Sub DoAction()
22![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
23
'添加事件内容
24![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
25
Me.Label1.Text = "child calls parents by evnet"
26![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
27
End Sub
28![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
29
End Class
30![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
31![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class FormChildClass FormChild
32![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
33
Inherits System.Windows.Forms.Form
34![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
35
Private obLogic As Logic
36![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
37![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Sub setParam()Sub setParam(ByRef obLogicParam As Logic)
38![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
39
Me.obLogic = obLogicParam
40![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
41
End Sub
42![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
43![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Private Sub Button1_Click()Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
44![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
45
obLogic.PassInf4Child()
46![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
47
End Sub
48![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
49
End Class
50![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
51![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
Public Class LogicClass Logic
52![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
53![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Delegate Sub PassInf4Own()Sub PassInf4Own()
54![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
55
Public Event PassInf4Parent As PassInf4Own
56![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
57![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Public Function PassInf4Child()Function PassInf4Child() As Boolean
58![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
59
RaiseEvent PassInf4Parent()
60![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
61
End Function
62![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
63
End Class
64
在4这个方法的基础上,我们想实现同一个父窗体下多个子窗体之间的调用和控制就方便多了,因为具体动作都是父窗体来实现的,子窗体只需要通过逻辑类传递一个消息就行了。比如说二少爷想让大少爷给他好吃的,大少爷不肯,那么二少爷和仆人都没辙,毕竟他们没有这个权力调动大少爷。但是二少爷让仆人告诉老爷,这事就好办了,老爷自然会让大少爷把东西给他弟弟并批评他:“你怎么不让着弟弟。”呵呵。
这都是比较简单的方法,是目前笔者所掌握的。有什么更好的方法,欢迎大家交流。