在 WinForm 表單設計中,常會使用到表單來傳值。 例如: FormA 開啟 FormB 後,想傳遞資料給 FormB ,或者 FormA 開啟 FormB 後,經過使用者的操作後, FormB 要將資料傳回 FormA 。 底下是這些相關的操作的備忘錄:
Form.Show() VS. Form.ShowDialog()
這二個方法都可以用來開啟表單,主要差別在於:
- Form.Show :以非強制回應表單(modaless)的方式顯示表單。
- Form.ShowDialog :以強制回應對話方塊(modal dialog)的方式顯示表單。也就是呼叫這個方法時,它隨後的程式碼都必須等到對話方塊關閉之後才會執行。
DialogResult 屬性:
DialogResult 屬性值,是關閉強制回應對話視窗時,要回應給父表單的狀態訊息。 你可以直接指定 Form.DialogResult 屬性值,以指定回應狀態。 或者對子視窗中的特定 Button ,設定其 DialogResult 屬性的值,用以表示要回傳給父表單的 DialogResult 屬性值。 當這些 Button 被 Click 之後,就會自動變更 Form.DialogResult 屬性。
public FormTestB() { InitializeComponent(); //對視窗中的特定 Button 設定其 DialogResult 屬性的值 bnYes.DialogResult = DialogResult.Yes; bnNo.DialogResult = DialogResult.No; bnCancel.DialogResult = DialogResult.Cancel; }
Dialog 視窗關閉時,執行個體不會結束
使用 ShowDialog 與 Show 開啟表單時,還有一個最大的差異點在於關閉表單時。 在非強制回應表單中,若使用者按了右上角的X關閉表單,子表單執行個體會被 Close 結束掉; 若在強制回應表單中,若使用者按了右上角的X關閉表單,子表單只會被 Hidden ,在父視窗中,你可以隨時再叫用該執行個體的 ShowDialog 方法來顯示子表單。 除非你不再使用到該子表單,你可以叫用 Form.Dispose 結束它的生命。
private void bnShow_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(textBox1.Text); formB.Show(); } private void bnShowDialog_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(textBox1.Text); DialogResult result1 = formB.ShowDialog(this); Console.WriteLine(result1.ToString()); DialogResult result2 = formB.ShowDialog(this); //without creating a new instance Console.WriteLine(result2.ToString()); formB.Dispose(); //no longer needed by your application. }
Dialog 視窗如何關掉,並回傳訊息
若打算關掉 Dialog 視窗,你可以叫用 Close() 方法來關掉強制回應表單,並且設定 DialogResult 屬性,以便告知主視窗強制回應表單的狀態。
private void bnShowDialog_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(); if (formB.ShowDialog(this) == DialogResult.Yes) { this.textBox1.Text = formB.Tag.ToString(); } formB.Dispose(); }
private void bnYes2_Click(object sender, EventArgs e) { this.Tag = textBox1.Text; this.DialogResult = DialogResult.Yes; this.Close(); }
如何判斷目前表單是哪一種顯示方式
當 FormB 被顯示時,你可以在 FormB 中,直接由 Form.Modal 屬性判斷目前視窗是哪一種開啟方式。 不過這個屬性值必須要等到 Form_Load 事件發生時才會有效,太早判斷會沒有意義,例如在 Form 的建構式中。
public FormB() { InitializeComponent(); if (this.Modal) { } //Modal值尚未設定 } private void FormB_Load(object sender, EventArgs e) { if (this.Modal) { MessageBox.Show("Modal Form"); } else { MessageBox.Show("Modaless Form"); } }
從 FormA 如何存取 FormB 中的資訊
透過 Constructor
若 FormA 開啟 FormB 的時候,想要傳遞資料給 FormB ,最簡單的方法就是直接由 Constructor 的參數來傳遞。
public FormTestB() { InitializeComponent(); //對視窗中的特定 Button 設定其 DialogResult 屬性的值 bnYes.DialogResult = DialogResult.Yes; bnNo.DialogResult = DialogResult.No; bnCancel.DialogResult = DialogResult.Cancel; } //新增一個含有參數的 Constructor public FormTestB(string para1) :this() { textBox1.Text = para1; }
private void bnShow_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(this.textBox1.Text); formB.Show(); }
透過公開方法或屬性
若 FormA 想要存取 FormB 上控制項的屬性值,你可以在 FormB 中自訂公開的方法或屬性來存取。
public void SetTextBox1(string txt) { textBox1.Text = txt; } public string TextBox1Text { get{ return textBox1.Text; } set{ textBox1.Text = value; } }
private void bnShow2_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(); //透過 public method 存取 formB.SetTextBox1(this.textBox1.Text); //透過 public property 存取 formB.TextBox1Text = this.textBox1.Text; formB.Show(); }
變更 FormB 控制項的 Modifier
若要存取 FormB 上控制項的屬性值,另外一個做法就是直接變更 FormB 上的控制項的 Modifier 屬性為 internal 或 public ,那麼在 FormA 中就可以直接存取 FormB 中的控制項屬性。 這個 Modifier 屬性值,在 C# 中,預設是 private ,所以必須變更為 internal 或 public 後,才可以由 FormA 中直接存取。 但是在 Vb.NET 中,預設是 Friend ,所以可以不必修改就可以直接讀取。
設定好modifier就可以由 A 表單中直接讀取 B 表單中的控制項的值。
private void bnShowDialog_Click(object sender, EventArgs e) { FormTestB formB = new FormTestB(textBox1.Text); if (result1 == DialogResult.Yes) { this.textBox1.Text = formB.textBox1.Text; } formB.Dispose(); }
從 FormB 如何存取 FormA 中的資訊
要由子表單存取父表單,基本上要先知道其父表單是誰,通常的做法是在子表單中加入一個可以傳入父表單的建構子。
private Form parentForm; public FormTestB(Form frm) { this.parentForm = frm; } private void FormTestB_Load(object sender, EventArgs e) { this.textBox1.Text = ((FormTestA)parentForm).TextBox1Text; }
public string TextBox1Text { get{ return textBox1.Text; } set{ textBox1.Text = value; } }
沒有留言:
張貼留言