窗体间传值的最佳方式

it2025-04-13  11

转自:http://bbs.csdn.net/topics/360140208

这个问题被问到相当多,很多网友都知道用属性,用委托。但是具体怎么做却不清楚。我在网上看到很多文章,虽然提出的方案可行,但是实现的都不好,于是自己动手写了一个例子给大家。希望这个例子足够简单完整。我将标题设定为“最佳实践”,意味着我觉得窗体传值应该有一个统一的,标准的模式给大家套用。我认为我提供的模式比较优雅,但是更优雅的设计是采用 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();          }      } }

简单分析下这个代码:模态传值的方法是:传入时可以使用构造函数,传出的时候首先判断是否用户是通过确定关闭的,如果是,那么用属性传出。这个做法也是框架库的做法,比如打开文件对话框。非模态的情况略微复杂:因为我们需要主窗体能和子窗体实时交互,为了同步主窗体和子窗体的数据,我们用了事件。有人问了,为什么我们不能让子窗体直接操作主窗体,这是因为考虑到对话框可以被重用,如果让它直接操作主窗口那么就限制死了这个子窗口只能被某个特定的主窗口调用。为了解除子窗体对调用者的耦合,我们使用事件。如果子窗体已经被显示,主窗体再次调用子窗体,那么通常我们希望激活子窗体而不是再显示一个。具体的实现参考代码。

转载于:https://www.cnblogs.com/lovezhangyu/p/3406079.html

相关资源:在WinForms程序里实现窗体传值的最佳实践 - ver 1.0
最新回复(0)