Form問(wèn)題是最基本的問(wèn)題,因?yàn)榫帉?/span>WinApp程序首先接觸的對(duì)象就是它,因此在論壇中對(duì)它而產(chǎn)生的問(wèn)題也最常見。
與Form相關(guān)的常見問(wèn)題大致分為如下的四類問(wèn)題。
第一類問(wèn)題:如何控制窗體的顯示順序;
第二類問(wèn)題:窗體之間的對(duì)象如何相互引用或操作;
第三類問(wèn)題:如何處理窗體唯一性問(wèn)題;
最后一個(gè)問(wèn)題:如何合理的關(guān)閉窗體或程序。
接下來(lái)先說(shuō)說(shuō)如何控制窗體的顯示順序。
很多編程者常常會(huì)遇到這樣的現(xiàn)象,例如,通過(guò)一個(gè)登錄窗體去打開一個(gè)主窗體,然后要在主窗體中想關(guān)閉這個(gè)登錄窗體。那么就有人出主意,你可以在打開主窗體的時(shí)候把登錄窗體自身傳進(jìn)去,然后在主窗體中調(diào)用它的Hide方法來(lái)隱藏。雖說(shuō)這樣可以暫時(shí)達(dá)到你所要的效果,但不是最合理的解決辦法。因?yàn)檫@樣做有如下兩個(gè)缺陷。
第一個(gè)就是,登錄窗體已經(jīng)完成使命,而資源沒(méi)有得到及時(shí)釋放;
其次就是,在窗體關(guān)閉的時(shí)候比較麻煩,需要找到登錄窗口,關(guān)閉自身的同時(shí)要關(guān)閉登錄窗體。
遇到此問(wèn)題的時(shí)候,首要的是分析窗體打開的順序以及相互關(guān)聯(lián)的條件,常見的類型無(wú)非就是主子或者先后這兩種。理解好第一點(diǎn)后,那么要學(xué)會(huì)合理使用ShowDialog和DialogResult這兩個(gè)好東西,前者屬于模式打開窗體,后者屬于窗體的返回值。
明白了這兩點(diǎn),就可以很方便的解決類似于登錄窗體的問(wèn)題,這方面的例子可以參看我的這篇文章。
http://blog.csdn.net/knight94/archive/2006/04/06/652394.aspx
文章中修改了一個(gè)WinApp的入口函數(shù)Main,那么并不意味著這個(gè)方法只能在這兒使用,它可以在很多方法中進(jìn)行使用,基本語(yǔ)法類似,這里我就不多說(shuō)了。
第二個(gè)要說(shuō)的是窗體之間的對(duì)象如何相互引用或者操作。
常見的類似問(wèn)題有:
1. 如何在子窗體訪問(wèn)到主窗體中的某某數(shù)據(jù);
2. 如何在子窗體中調(diào)用主窗體中的某某方法;
3. 如何在子窗體關(guān)閉的時(shí)候去更新主窗體的某某數(shù)據(jù);
對(duì)于如上的三個(gè)問(wèn)題,完全可以由如下兩種方法來(lái)完成。
1. 當(dāng)數(shù)據(jù)是子窗體顯示的必要條件的話,通過(guò)修改子窗體的構(gòu)造函數(shù)來(lái)進(jìn)行傳遞數(shù)據(jù);
2. 如果是不定時(shí)的訪問(wèn),則可以通過(guò)委托來(lái)實(shí)現(xiàn)。
對(duì)于第一點(diǎn),我就不多說(shuō)了,對(duì)于第二點(diǎn),我用如下的例子來(lái)說(shuō)明。
首先在子窗體中,需要如下:
//Define two delegate methods to get or set textbox value in main form
public delegate void SetTextValue( string TextValue );
public delegate string GetTextValue( );
// In sub-form class
// Handler for methods from main form
private SetTextValue SetText = null;
private GetTextValue GetText = null;
// Call methods as follows
string strValue = GetText();
SetText( strValue + DateTime.Now.ToString() );
除了如上一些操作外,還需要修改子窗體的構(gòu)造函數(shù),來(lái)接收這兩個(gè)delegate方法,這里就不多說(shuō)了。
至于主窗體,首先要為這兩個(gè)委托來(lái)實(shí)現(xiàn)對(duì)應(yīng)函數(shù),例如:
/// <summary>
/// Get textbox's text for other forms
/// </summary>
/// <returns></returns>
private string GetValue()
{
return yourTextBox.Text;
}
/// <summary>
/// Set textbox's text for other forms
/// </summary>
/// <param name="sValue"></param>
private void SetValue( string sValue )
{
yourTextBox.Text = sValue;
}
那么調(diào)用子窗體的時(shí)候就比較簡(jiǎn)單了。
// Create subform and show it
yourSubForm myForm = new yourSubForm(
new SetTextValue( SetValue ),
new GetTextValue( GetValue ) );
myForm.ShowDialog();
這樣一個(gè)通過(guò)委托來(lái)操縱主窗體的例子就完成了。這里需要注意的一點(diǎn),如果在子窗體中大量使用到主窗體的數(shù)據(jù)的話,那我建議你重新考慮窗體架構(gòu),這意味著你目前的窗體架構(gòu)不合理。
有人說(shuō)了,僅僅為了訪問(wèn)一個(gè)成員就需要?jiǎng)趲焺?dòng)眾編寫委托,多麻煩,直接public成員,或者使用static靜態(tài)成員多方便,那么對(duì)于這兩點(diǎn)的壞處,我這里就不多說(shuō)了,參看我的這篇文章你就會(huì)明白。
http://blog.csdn.net/knight94/archive/2006/06/04/772886.aspx
第三類問(wèn)題,窗體的唯一性問(wèn)題,這個(gè)問(wèn)題我在這兒就不多說(shuō)了,因?yàn)檫@類問(wèn)題我在如下的文章已經(jīng)說(shuō)得很透徹了。
http://blog.csdn.net/knight94/archive/2006/05/24/752783.aspx
最后一個(gè)問(wèn)題,如何合理的關(guān)閉窗體和程序。很多人關(guān)閉了窗體,發(fā)現(xiàn)程序進(jìn)程還在,就不知道如何來(lái)操作了。大多數(shù)的問(wèn)題,都是因?yàn)榈谝活悊?wèn)題而產(chǎn)生的連鎖反應(yīng)。所以我不建議使用Application.Exit來(lái)關(guān)閉程序,雖說(shuō)C#寫的是托管程序,內(nèi)存的釋放可以不用操心,但是好的編碼習(xí)慣,有利于在編寫復(fù)雜程序的時(shí)候能得心應(yīng)手。
那么如何正確的關(guān)閉一個(gè)窗體或者一個(gè)程序呢。
如果不能正常關(guān)閉的原因是由于第一類問(wèn)題造成的話,按照第一類的方法去修改窗體顯示順序,來(lái)達(dá)到合理的步驟。前期的正確,才能保證后期的能通過(guò)this.Close進(jìn)行關(guān)閉窗體以及程序。
如果是子窗體要關(guān)閉連鎖到主窗體關(guān)閉的話,這類問(wèn)題也占一大部分,那么解決此類問(wèn)題可以采用第二類問(wèn)題所提到委托方法。
那么還有一些窗體關(guān)閉,程序沒(méi)有正常關(guān)閉,是由于子線程沒(méi)有關(guān)閉的問(wèn)題,這部分留到線程匯總部分再說(shuō)。
用C#寫程序不難,如何編寫正確的程序才是至關(guān)重要。此時(shí)再回過(guò)頭看看前面所說(shuō)的四類問(wèn)題的解決方法,其實(shí)不難發(fā)現(xiàn)這些方法并沒(méi)有用到特別深的技術(shù),都是非常普通的方法。俗話說(shuō),平凡中見真知,只要把所學(xué)的方法正確應(yīng)用到編碼當(dāng)中,那么你處理此類問(wèn)題也能游刃有余。