以前如果碰到子窗體(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文本控件的內容馬上更新了.