2015-06-30 33 views
1

我的Winform應用程序具有3種形式:MainForm,Form1和Form2。 MainForm有一個UserControl;應用程序啓動時,它調用的MainForm,MainForm中會被加載並添加Form1中到用戶控件:如何使用委託在UserControl上從活動窗體獲取值到另一窗體

private void MainForm_Load(object sender, EventArgs e) 
{ 
    Form1 frm = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true }; 
    xtraUserControl1.Controls.Add(frm); 
} 

在Form1上,我使用委託:

public delegate void Tranferdata(string txt); 
    public Tranferdata _tranfer; 
    private void Gettxt(string txt) 
    { 
     tbx_Recieve.Text = txt; 
    } 

Form1上有一個按鈕來調用窗體2:

private void button1_Click(object sender, EventArgs e) 
{ 
    Form2 frm2 = new Form2(); 
    frm2.ShowDialog(this); 
} 

將Form2的Form2上後關閉值發送到Form1,代碼:

private void Form2_FormClosed(object sender, FormClosedEventArgs e) 
{ 
    using (Form1 frm1 = (Form1)this.Owner) 
    { 
     frm1._tranfer(tbx_Numb.Text); 
    } 
} 

private void button1_Click_1(object sender, EventArgs e) 
{ 
    this.Close(); 
} 

但我的代碼無法正常工作。它在'使用(Form1 frm1 =(Form1)this.Owner)'並且顯示System.InvalidCastException時崩潰。 我該如何解決這個問題?

+0

可能重複[怎麼回事從C#中的窗體?](http://stackoverflow.com/questions/5233502/how-to-return-a-value-from-a-form-in-c) – Melvin

+1

不要把它放在'使用'語句時,如果你這樣做,否則你將處置傳遞給閉合方法的'Form1'實例。當你想完成它時想要銷燬對象,只能使用'using'。還有其他一些原因,爲什麼它不起作用('sender'是一個Form2,而不是Form1),雖然你正在使用大錘與代表一起拍照,然後轉移到... –

+0

感謝您的關心,但我不想那樣。我最好使用委託@Melvin – Camambeou

回答

0

我找到了解決這個問題: 在Form 2:

public void SetParent(Form1 frm) 
{ 
    frm1 = frm; 
} 

,並在活動通話窗口2調用它在表格1:

private void button1_Click(object sender, EventArgs e) 
{ 
    Form2 frm2 = new Form2(); 
    frm2.SetParent(this); 
    frm2.ShowDialog(); 
} 
0

它在該行上崩潰的原因是因爲您沒有將Form1設置爲Form2的所有者。

要解決,首先必須Form1中爲類變量,而不是作爲一個局部變量:

Form1 form1; 
private void MainForm_Load(object sender, EventArgs e) 
{ 
    form1 = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true }; 
    xtraUserControl1.Controls.Add(form1); 
} 

然後你可以用它來分配窗體2的擁有者,當你創建:

private void button1_Click(object sender, EventArgs e) 
{ 
    Form2 frm2 = new Form2(); 
    frm2.Owner = form1; 
    frm2.ShowDialog(this); 
} 

而且也像Ron Beyer在他的評論中提到的那樣,考慮刪除使用語句,它將關閉Form1,它聽起來不像你想要做的那樣。

現在,雖然這種方法可行,但您在這裏應該考慮一些問題: 爲什麼您首先選擇使用「所有者」屬性?你真的需要它嗎? Form1作爲Form2的所有者意味着當Form1關閉時Form2將關閉。由於您在Form2上使用ShowDialog,它將阻止用戶在Form2顯示時關閉Form1,因此看起來不需要。 如果使用Owner屬性的原因僅僅是爲了使用委託,而不是您剛纔向Form2添加屬性的類型爲Form1,而這會讓您輸入安全性和高級代碼。

但還有更好的辦法:MainForm可以註冊到Form2的Closed事件並在Form1上調用該方法。這將刪除不需要的依賴項(Form2和Form1根本不會了解對方),使代碼更健康。

+0

我重寫我的代碼根據您的建議,但我再次墜毀,在** frm1._tranfer(tbx_Numb.Text); **(類型'System.NullReferenceException'異常)。我認爲問題是程序定義的Form2的父窗體是MainForm,而不是Form1,因爲Form1被添加到MainForm上的UC – Camambeou

+0

未分配frm1或tbx_Numb。在該行上放置一個斷點,調試應用程序,直至到達斷點並檢查兩個值以查看哪個未分配。然後相應地修復你的代碼。如果您仍然需要幫助,請在此處發佈您的新代碼,我會盡力提供幫助。 – tzachs

+0

我不知道如何在評論中寫我的代碼。我的代碼被修改了一點:不使用「使用(Form1 frm1 =(Form1)this.Owner)」但「Form1 frm1 =(Form1)this.Owner」。請,我需要幫助 – Camambeou

相關問題