老题新理解-在话winform之间的窗体传值
也许当你看到标题的时候,你会想,这窗体间传值方法就这么多,无非就是那几种:
1.静态变量(这个最简单)
非时性的传递:
1.窗体的属性
2.构造函数
时时性的传递:
1.委托
2.静态变量(这个最简单)
几乎很多人都可以很根据简单方便的原则选用静态变量的方式。如果少量的数据传送,完全没有问题,但是数据量大,效率的时候,个人觉得使用委托应该是最有效的。
我将记录我第一次接触窗体传值的时候过程:
窗体与窗体之间,就好比两栋房子,将房子一的信息传入到房子二,那就必须有一个跑腿的。(变量)
一,那这个变量可以做为一个共用变量,大家都可以使用,需要改变的时候直接赋值就可以了。
那很简单呀:
public static string commonvalue;
二,如果我只需要将提示他传值呢?(不规定特定变量)使用委托的方式 (上网查询后了解的)
子窗体:textC 一个textbox
代码:
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 FormPost { public partial class textC : Form { public textC() { InitializeComponent(); } //为textC声明一个公有字段(也可以封装成属性) public DelChangetext changetxt; private void textBox1_TextChanged(object sender, EventArgs e) {
//判断委托变量是否为空 if (changetxt!=null) {
//调用方法 changetxt(this.textBox1.Text); } } }
//委托类 public delegate void DelChangetext(string txt); }
父窗体:textF 一个button 一个textbox
代码:
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 FormPost { public partial class textF : Form { public textF() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { textC child = new textC();
//为子窗体的字段赋值上值 child.changetxt = new DelChangetext(txt => this.textBox1.Text = txt); child.Show(); } } }
至于和利用属性传值和构造函数传值基本上都是同一个道理。
这里,窗体间的传值都是一个意思,关键是直接传递改变的值(静态变量),还是传递的一个命令(方法),还有csdn上的大神的方法,更好,下面我贴上代码 :
为了实现这个例子,你需要准备2个窗口,一个叫MainForm,上面至少需要一个richTextBox,两个工具栏按钮。
另一个叫 MyDialog 的子窗口,上面有一个 textBox1,一个 Button,作为确定按钮。
两个工具栏按钮分别实现两种形式的窗体调用,模态的和非模态的。
模态的意思是,我们打开对话框,将值传进取,操作完成确定,主窗体再获得对话框的值。
非模态的意思是,我们打开对话框,可以在不关闭窗口的情况下和主窗体交互,主窗体可以即时获得子窗体的值。类似记事本的查找替换对话框。
下面是代码:
主窗体:
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(); } } } }
子窗体:
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。
有任何问题可以提问。代码有问题,或者更好的办法,也欢迎批评。
个人总结:
关键还是如何思考问题和如何正确的描述问题