父子窗口传递数据主要通过属性和委托完成。
对话框主要分为模态和非模态两种对话框。本文参考http://bbs.csdn.net/topics/360140208一文实现这个功能。
父窗口
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://bbs.csdn.net/topics/360140208