[英]Winform & user control - C#
我有一個窗體和一個UserControl。 UserControl有一個菜單,而窗體有一個Tabstrip(常規,食品,維生素等)。
在UserControl中,我有以下代碼:(表單名稱為frmForm,表單中的選項卡名稱為tabGeneral,tabFood,tabVitamins)
frmForm fm=new frmForm();
fm.tabMain.Selected=tabVitamins;
我從UserControl調用這些行以捕獲要在表單上選擇的選項卡,但是它沒有選擇“維生素”選項卡。
我要去哪里錯了? 我在表單中將訪問標簽指定為“受保護的內部”。
請指教。
謝謝,卡西克
編寫new frmForm()
,您將創建一個全新的frmForm
實例,然后將其丟棄。
要獲取保存您的控件的frmForm
實例,請調用FindForm()
方法並將其frmForm
為frmForm
。
例如:
frmForm myForm = FindForm() as frmForm;
if(myForm != null)
myForm.tabMain.SelectedTab = myForm.tabVitamins;
如果控件采用其他形式,則此代碼將不執行任何操作。
順便說一下,.Net不支持匈牙利符號。
您的表單應該命名為MainForm
。
SLaks已經正確指出了您的基本錯誤,並通過調用方法'FindForm,給出了一種有效的方法示例,該方法用於獲取用戶控件所在的表單。
對您而言,記住一個UserControl(和所有Controls)也具有'Parent屬性可能是有價值的,但是,當然,一個UserControl可以放置在窗體上的另一個Control內(例如您的UserControl可以在Panel內)在窗體上):在這種情況下,UserControl的父控件將是它在窗體(如面板)中的控件,而不是窗體本身,但是'FindForm將做正確的事來獲取您所在的窗體。
但是,每次使用'FindForm時,您都在調用Method,並且“最佳實踐”建議您要做的是在運行時將對Form的引用“注入”到UserControl中,以便它始終可以訪問其Form。屬性,而無需調用“方法”。
在你的榜樣,在實踐層面上,這(調用方法)可能使在性能上幾乎沒有差別,但是,恕我直言,當你到一個地方與WinForms和.NET,你可能有一個用戶控件, 將需要訪問它的Parent Form非常頻繁,這會有所回報,從長遠來看,這是一種更好的結構化代碼以進行維護的更好方法。
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;
}
或者在需要時,一次設置UserControl的'ParentForm屬性。 因此,您無需使用方法'FindForm()。
在這種情況下,如果只希望訪問UserControl的父窗體上的特定控件(如TabControl),則可能會認為您希望將所設置的屬性設置為TabControl類型,而不是Form類型:上面顯示的相同編碼技術可以在UserControl中使用:
private TabControl mainFormTabControl;
public TabControl MainFormTabControl
{
set { mainFormTabControl = value; }
}
恕我直言,這是您在運行時動態創建UserControl時的最佳策略,正如Wes建議的那樣,使用重載的構造函數。 使用重載的構造函數在.NET中有很多很多其他用途,您會發現。
祝好運 !
您不應在用戶控件內創建新的frmForm()。 您可以將對frmForm的引用傳遞給用戶控件。
在您的用戶控件構造函數中,嘗試執行以下操作。
private frmForm fm;
public YourUserControl(frmForm fm)
{
this.fm = fm;
}
然后,您可以使用。
fm.tabMain.Selected=tabVitamins;
有幫助嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.