以前如果碰到子窗体(ShowDialog显示)中的的改变会影响父窗体子控件内容时,要么就在ShowDialog()结束后更新数据,要么就把子控件设置为public。
1.ShowDialog方式:不能立马看到更新结果,ShowDialog会阻断当前线程,一定要等到子窗体关闭后,线程才被唤醒。
2.把控件设置了public 需要实例化父窗体,父窗体是一个大对象,虽然最终会被GC回收,GC也不知道什么时候才会把这个大对象销毁掉(书上说要等到内存不够用的时候),但始终会占用内存一段时间,影响性能不说,只为访问一个子控件而实例化一个大对象,得不偿失。
3.使用事件解决问题,既然当前主线程被锁定了,用户自己无法更新数据,这时候可以委托别人来做事(委托的好处),就像自己不能打官司一样,可以请律师来帮忙。顺便自己也可以复习一下事件与委托之间的关系:事件就是一个委托。
我们随便新建一个Winform项目,再新建两个窗体MainForm.cs,ChildForm.cs。再新建一个CallBack.cs类。
/// <summary> /// 用于改变父窗体子控件内容的委托 /// </summary> /// <param name="text"></param> public delegate void MyTextChangedHandler(string text); public class CallBack { /// <summary> /// 申明一个用于触发改变父窗体子控件内容的事件 /// </summary> public event MyTextChangedHandler MyTextChangedEvent; /// <summary> /// 通过调用此方法来触发事件 /// </summary> /// <param name="text">传回来的值</param> public void ChangeText(string text) { if (MyTextChangedEvent!=null) { MyTextChangedEvent(text); } } }
public partial class MainForm : Form { public MainForm() { InitializeComponent(); } //弹出子窗体,将CallBakc对象传递给子窗体 private void button1_Click(object sender, EventArgs e) { CallBack call = new CallBack(); //订阅改变父窗体文本控件文本的事件 call.MyTextChangedEvent += new MyTextChangedHandler(MyTextChanged); ChildForm frmChild = new ChildForm(call); frmChild.ShowDialog(); } //编写事件,改变文本内容 private void MyTextChanged(string text) { txtValue.Text = text; } }
public partial class ChildForm : Form { public ChildForm() { InitializeComponent(); } private CallBack callBack; public ChildForm(CallBack call) { InitializeComponent(); callBack = call; } //马上传值 private void button1_Click(object sender, EventArgs e) { callBack.ChangeText("我是任我行!!!"); } }
运行结果:
当我点击马上传值的时候,父窗体的txtValue文本控件的内容马上更新了.