2009-12-24 156 views
1

我有一個窗體和一個UserControl。 UserControl有一個菜單,表單有一個tabtrip(General,Food,Vitamins等)。Winform和用戶控件 - C#

在用戶控件的,我有以下代碼:(表格名稱是frmForm,形式的標籤名稱是tabGeneral,tabFood,tabVitamins)

frmForm fm=new frmForm(); 
    fm.tabMain.Selected=tabVitamins; 

我打電話從用戶控件這些線捕捉選項卡以在表單上進行選擇,但不會選擇維生素選項卡。

我哪裏錯了?我有訪問說明符作爲表單中的標籤保護內部。

請指教。

感謝, Karthick

回答

7

當你寫new frmForm(),你要創建的frmForm一個全新實例,然後將其丟棄。

若要獲取控制您的控件的frmForm實例,請調用FindForm()方法並投射到frmForm

例如:

frmForm myForm = FindForm() as frmForm; 
if(myForm != null) 
    myForm.tabMain.SelectedTab = myForm.tabVitamins; 

如果控制一些其他的形式,該代碼不會做任何事情。


順便說一下,匈牙利語符號在.Net中被皺起了眉頭。
您的表單可能應該被命名爲MainForm

+0

謝謝SLaks。完美,我改變了myForm.tabMain.SelectedTab = frmForm.tabVitamins; 至 myForm.tabMain.SelectedTab = myForm.tabVitamins; – Karthick 2009-12-24 01:33:22

+0

是的,你是對的。我修正了這一點。 – SLaks 2009-12-24 01:40:04

+0

很好的答案,幫助了我。謝謝。 – MikeMalter 2011-05-20 23:49:14

1

你不應該創建新frmForm()的用戶控件中。您可以將對frmForm的引用傳遞給用戶控件。

在您的用戶控件構造函數中嘗試類似這樣的操作。

private frmForm fm; 

public YourUserControl(frmForm fm) 
{ 
    this.fm = fm; 
} 

然後你可以使用。

fm.tabMain.Selected=tabVitamins; 

這有幫助嗎?

+0

這會阻止設計人員使用該控件。 – SLaks 2009-12-24 01:19:18

+0

我剛剛在VS 2008中試過,看起來很好。你爲什麼認爲它會阻止設計者使用控制器? – wes 2009-12-24 01:21:28

+0

設計人員要求控件具有公共無參數構造函數。 – SLaks 2009-12-24 01:22:04

3

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中使用的構造函數。

祝你好運!