簡體   English   中英

從子窗體訪問主窗體中的控件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM