SLaks已經正確地指出了你的根本錯誤,並給出了一個有效的方法示例,通過調用方法FindForm來獲取UserControl所在的窗體。
記住一個UserControl(和所有控件)也有一個'Parent屬性,但是當然,UserControl可以放在窗體的另一個控件內(比如你的UserControl可能會有價值在窗體中的Panel上):在這種情況下,UserControl的Parent將是它在Form中的控件(比如Panel),而不是Form本身,但是'FindForm將做正確的事情來讓你的Form上。
但是,每次使用FindForm時,您都會調用Method,並且「最佳實踐」表明您想要執行的操作是在運行時將對該Form的引用「注入」到UserControl中,以便它可以總是輕鬆地訪問它的Form屬性,而不用調用'Method'。
在你的例子中,在實際的層面上,這個(調用方法)可能在性能上幾乎沒有什麼區別,但是,當你到達一個使用WinForms和.NET的地方時,你可能會有一個用戶控件需要頻繁訪問其父窗體,這將會得到回報,並且從長遠來看,這是更好地構建代碼的方式,以便進行維護。 Wes向您展示了一種您可以「嵌入」(注入)UserControl的託管窗體的方法:使用UserControl的重載構造函數。但是這需要您修改標準WinForms中的Designer.cs文件,我強烈建議您不要這樣做,儘管它可以工作。特別是如果你在.NET中只是「腳踏實地」,我強烈建議你不要修改它,或者任何與Form的構造函數和它的內部調用有關的任何東西:InitializeComponent();另外,隨着WinForms的進展,你將遇到許多你想要「對象」實例(一個控件,一個窗體,一個類的實例)的實例來包含對其他「對象。
如果你能理解並使用一個簡單的使用「注射液」在這裏,你將取得進展,使自己準備在未來處理更復雜的.NET編程。
另一種方法是在UserControl中放置一個公共屬性,該屬性可以在MainForm的代碼中設置。在UserControl中有如下所示:
private frmForm ParentForm;
public frmForm UCParentForm
{
set { ParentForm = value; }
}
這樣,就要在你的主窗體的代碼,也許在這樣的Load事件:
private void frmForm_Load(object sender, EventArgs e)
{
TheUserControl.UCParentForm = this;
}
或者當你需要,可以設置用戶控件的「ParentForm屬性一次。所以你已經使用方法FindForm()消除了。
在這種情況下,如果您只想訪問UserControl的父表單上的某個特定控件(如TabControl),則可以考慮將該屬性設置爲TabControl類型,而不是Form:相同的編碼如上所示技術可以在該用戶控件中使用:
private TabControl mainFormTabControl;
public TabControl MainFormTabControl
{
set { mainFormTabControl = value; }
}
IMHO,它是當你在運行時動態地創建用戶控件,使用重載的構造,如韋斯所暗示的,是最好的策略。並且使用重載的構造函數有許多其他許多.NET中使用的構造函數。
祝你好運!
謝謝SLaks。完美,我改變了myForm.tabMain.SelectedTab = frmForm.tabVitamins; 至 myForm.tabMain.SelectedTab = myForm.tabVitamins; – Karthick 2009-12-24 01:33:22
是的,你是對的。我修正了這一點。 – SLaks 2009-12-24 01:40:04
很好的答案,幫助了我。謝謝。 – MikeMalter 2011-05-20 23:49:14