页面传值

这个问题被问到相当多,很多网友都知道用属性,用委托。但是具体怎么做却不清楚。

我在网上看到很多文章,虽然提出的方案可行,但是实现的都不好,于是自己动手写了一个例子给大家。希望这个例子足够简单完整。

我将标题设定为“最佳实践”,意味着我觉得窗体传值应该有一个统一的,标准的模式给大家套用。我认为我提供的模式比较优雅,但是更优雅的设计是采用 MVC。因为那样会大大增加例子的复杂度,不适合新手,没有给出。

为了实现这个例子,你需要准备2个窗口,一个叫MainForm,上面至少需要一个richTextBox,两个工具栏按钮。
另一个叫 MyDialog 的子窗口,上面有一个 textBox1,一个 Button,作为确定按钮。

两个工具栏按钮分别实现两种形式的窗体调用,模态的和非模态的。

模态的意思是,我们打开对话框,将值传进取,操作完成确定,主窗体再获得对话框的值。
非模态的意思是,我们打开对话框,可以在不关闭窗口的情况下和主窗体交互,主窗体可以即时获得子窗体的值。类似记事本的查找替换对话框。

下面是代码:

主窗体:
C# code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;
 
namespace  WindowsFormsApplication1
{
     public  partial  class  MainForm : Form
     {
         public  MainForm()
         {
             InitializeComponent();
         }
 
         private  MyDialog m_dlg;
 
         private  void  toolStripButton1_Click( object  sender, EventArgs e)
         {
             MyDialog dlg =  new  MyDialog(richTextBox1.Text);
             if  (dlg.ShowDialog() == DialogResult.OK)
             {
                 richTextBox1.Text = dlg.TextBoxValue;
             }
         }
 
         private  void  toolStripButton2_Click( object  sender, EventArgs e)
         {
             if  (m_dlg ==  null )
             {
                 m_dlg =  new  MyDialog(richTextBox1.Text);
                 m_dlg.TextBoxChanged +=  new  EventHandler(
                     (sender1, e1) =>
                     { richTextBox1.Text = m_dlg.TextBoxValue; }
                 );
                 m_dlg.FormClosed +=  new  FormClosedEventHandler(
                     (sender2, e2) => { m_dlg =  null ; }
                 );
                 m_dlg.Show( this );
             }
             else
             {
                 m_dlg.Activate();
             }
         }
     }
}


子窗体
C# code
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using  System;
using  System.Collections.Generic;
using  System.ComponentModel;
using  System.Data;
using  System.Drawing;
using  System.Linq;
using  System.Text;
using  System.Windows.Forms;
 
namespace  WindowsFormsApplication1
{
     public  partial  class  MyDialog : Form
     {
         public  event  EventHandler TextBoxChanged;
 
         public  string  TextBoxValue 
         {
             get  return  textBox1.Text; }
             set  { textBox1.Text = value; } 
         }
 
         public  MyDialog() :  this ( "" ) { }
 
         public  MyDialog( string  Param)
         {
             InitializeComponent();
             TextBoxValue = Param;
         }
 
         private  void  textBox1_TextChanged( object  sender, EventArgs e)
         {
             if  (TextBoxChanged !=  null )
                 TextBoxChanged( this , e);
         }
 
         private  void  button1_Click( object  sender, EventArgs e)
         {
             Close();
         }
     }
}


简单分析下这个代码:

模态传值的方法是:传入时可以使用构造函数,传出的时候首先判断是否用户是通过确定关闭的,如果是,那么用属性传出。
这个做法也是框架库的做法,比如打开文件对话框。

非模态的情况略微复杂:因为我们需要主窗体能和子窗体实时交互,为了同步主窗体和子窗体的数据,我们用了事件。有人问了,为什么我们不能让子窗体直接操作主窗体,这是因为考虑到对话框可以被重用,如果让它直接操作主窗口那么就限制死了这个子窗口只能被某个特定的主窗口调用。为了解除子窗体对调用者的耦合,我们使用事件。如果子窗体已经被显示,主窗体再次调用子窗体,那么通常我们希望激活子窗体而不是再显示一个。具体的实现参考代码。

完整的代码在此:http://download.csdn.net/source/3169257。编译运行这个代码需要 .NET Framework 4.0。

有任何问题可以提问。代码有问题,或者更好的办法,也欢迎批评。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值