在WinForms程序里实现窗体传值的最佳实践

threenewbee 2011-04-07 07:06:31
加精
这个问题被问到相当多,很多网友都知道用属性,用委托。但是具体怎么做却不清楚。

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

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

为了实现这个例子,你需要准备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。

有任何问题可以提问。代码有问题,或者更好的办法,也欢迎批评。
...全文
42646 424 打赏 收藏 转发到动态 举报
写回复
用AI写文章
424 条回复
切换为时间正序
请发表友善的回复…
发表回复
limufeng27 2013-12-02
  • 打赏
  • 举报
回复
引用 95 楼 wuyazhe 的回复:
其实,如果不考虑耦合。最简单办法就是在一个公共地方,弄个静态变量。。。
具体怎么做,我是刚学没多久,了解的少, if (comboBox1.Text.Equals("学生登录")) { student stu = new student(); stu.Show(); } else { teacher tea = new teacher(); tea.Show(); } 我是想在student窗体中读取Form1窗体中textbox1.text的值,目的是获取用户名!
二大爷来了 2013-12-01
  • 打赏
  • 举报
回复
好的 看看哈 谢谢
sbycom 2013-11-27
  • 打赏
  • 举报
回复
谢谢楼主分享经验,楼主的帖子是我茅塞顿开!
江湖影 2013-11-27
  • 打赏
  • 举报
回复
学习了,谢谢分享
zhusongwen 2013-11-21
  • 打赏
  • 举报
回复
窗体传值学习了,谢谢。。。
北京大白兔 2013-11-01
  • 打赏
  • 举报
回复
学习了,谢谢大家的分享
jwh2004 2013-11-01
  • 打赏
  • 举报
回复
收藏----------
卧_槽 2013-10-31
  • 打赏
  • 举报
回复
我一般会有一个窗体注册类,所有的窗体都通过该类实例化。这样无论想要查找哪个窗体的实例,只需要有窗体名或者类型就可以查找到。在多tab展示的时候比较较方便。
u012436959 2013-10-31
  • 打赏
  • 举报
回复
学习了,受益了,谢谢楼主!
xnyun1207 2013-08-23
  • 打赏
  • 举报
回复
我先潜水学习,待学成时候再来讨论,先学习了!
super_admi 2013-08-15
  • 打赏
  • 举报
回复 1
虽然不知道你们在说什么,但看起来很厉害的样子。
houzp 2013-08-02
  • 打赏
  • 举报
回复
好东西,顶起来
yueyaquan 2013-07-27
  • 打赏
  • 举报
回复
又学到了一种窗体间传值的方法!
墨雪子竹 2013-06-28
  • 打赏
  • 举报
回复
新人,表示要好好学习
zk911 2013-06-26
  • 打赏
  • 举报
回复
http://download.csdn.net/source/3169257 这个貌似打不开
zk911 2013-06-26
  • 打赏
  • 举报
回复
不错 学习了!!! 谢谢分享经验
haibingxinyi 2013-06-25
  • 打赏
  • 举报
回复
这个学习了,好东西
敌敌畏耶 2013-06-25
  • 打赏
  • 举报
回复 1
LZ 出了 用这种感委托事件的方法将子窗体的值传入父窗体,还有什么方法呢?当子窗体关闭的时候,父窗体就显示子窗体传过来的值,怎么实现呢···
jiaozg19860409 2013-06-23
  • 打赏
  • 举报
回复
学习了,下来好好理解下
u011182701 2013-06-23
  • 打赏
  • 举报
回复
这种其实就是类似构造函数的方法吧。
加载更多回复(307)

110,526

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧