[英]Accessing a control in a main form from a child form
我有一個帶有 3 個主面板的主窗體:
歌曲選擇在子面板中完成(通過datagrid
),我想將歌曲名稱發送到頂部面板,以標簽song_played
開頭(在主窗體中)。
這是我打開子表單的方式(單擊菜單):
private void openChildFormInPanel(Form childForm)
{
if (activeForm != null)
activeForm.Close();
activeForm = childForm;
childForm.TopLevel = false;
childForm.FormBorderStyle = FormBorderStyle.None;
childForm.Dock = DockStyle.Fill;
panelChildForm.Controls.Add(childForm);
panelChildForm.Tag = childForm;
panelChildForm.Parent = this;
childForm.BringToFront();
childForm.Show();
}
panelChildForm
是位於主窗體中的子面板。
在我觸發的點擊事件中:
openChildFormInPanel(new Stats_form());
在我的子表單中,我嘗試了幾種解決方案,但我有一個異常System.NullReferenceException
因為父表單始終為null
:
this.Owner.Controls["song_played"].Text = (string)dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[2].Value;
我也試過:
((Form1)this.Owner).lablSetText((string)dataGridView1.Rows[dataGridView1.CurrentRow.Index].Cells[2].Value);
Form1
是我的主表單的名稱, labSetText
是一個用於設置主表單上標簽文本的函數。
最后的,
this.Parent.Controls["song_played"].Text = " dfgdfggdf";
觸發相同的異常
任何幫助表示贊賞:)
您可以繼續在調試器中環顧四周 - Quick Watch 會有所幫助 - 最終您會在childForm
實例上找到它的屬性, this
屬性允許您“向上”返回主 for 並“向下”返回到頂部面板。
我想建議另一種方法,雖然它不那么脆弱。
與其只為帶有數據網格視圖的子表單創建一個Form
,不如派生出您自己的表單並添加一個事件:
public SongSelectorForm : Form
{
public event EventHandler<String> SongChanged;
private void OnDataGridViewClick(object sender, EventArgs e)
{
SongChanged?.Invoke(this, "New Song Name"); //Taken from the data grid view.
//N.B. ?.Invoke is a safe way of calling the event handler in case no one is listened.
}
}
現在在 MainForm 中,當您添加 ChildForm 時,您可以訂閱該事件:
private void openChildFormInPanel(SongSelectorForm childForm)
{
//snip the above
childForm.SongChanged += HandleSongChange;
}
//We are adding a new method to the main form now to specifically handle a song change event from somewhere.
private void HandleSongChange(object sender, String songName)
{
this.TopForm.SongName = songName; //or whatever you use to update the songname in the top form.
}
由於主窗體是“父窗體”,因此它知道它的子窗體是有道理的。 使用事件是“父母”在孩子們不了解彼此的情況下編排孩子們的行為的一種方式。
我添加了一個TopForm.SongName
,以便“父級”可以更輕松地與 TopForm 對話,而無需知道底層控件是什么:
例如
//in topform
public String SongName
{
get { return someControl.Text; }
set { someControl.Text = value; }
}
這允許您在 TopForm 中更改內容,但仍然保持 Mainform 更改 SongName 的簡單方法,而無需更改它。
您對 C# 了解得越多,您就會發現可以使用接口來定義這些組件之間的“契約”,這樣它們之間的相互了解就會減少,從而可以更輕松地更改某一部分,而不必擔心會破壞其他任何部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.