2016-06-09 42 views
0

我試圖找到一個UserControl的ParentForm,所以我可以掛鉤一些事件處理程序。我試圖在用戶控件一個ParentChanged事件處理程序這樣做,例如:加載期間找到UserControl的ParentForm

ParentChanged += delegate(object sender, EventArgs args) 
{ 
    ParentForm.SomeEvent += ... 
} 

而且如果用戶控件的父恰好是這種形式的工作正常。但是,如果將UserControl嵌入到容器控件(本例中爲SplitContainer)中,則在將容器控件添加到頂層窗體的控件(如InitializeComponent方法中的控件)之前,將UserControl添加到容器控件中。也就是說,InitializeComponent()從樹葉上開始建立層次結構,因此葉子不知道在施工過程中最終會放置什麼樣的形式。

因此,當ParentChanged事件觸發時,UserControl上的ParentForm爲null,並且當UserControl的父級父級更改時,我沒有得到ParentChanged事件。我可以爲父母的ParentChanged事件添加監聽器,但是我必須在整個控制層次上這樣做,這不是特別優雅。

我基本上喜歡得知何時ParentForm更改UserControl的通知。但是沒有這樣的事件。我可以掛載Load事件之類的東西,但this表示,如果它在MDI容器中,每次顯示控件時都會觸發它。 MSDN文章建議把東西放在構造函數中,但這正是我現在正在做的事情,並且由於事物初始化的時機,它並沒有解決問題。

任何想法?

+0

一種可能性是顛倒的依賴。父表單可以將您的控件訂閱到自己的事件中(例如,通過'UserControl'的公共回調傳遞它)。你能分享這個事件的使用細節,你將在'UserControl'中做些什麼? – Sinatr

+0

'myUserControl.FindForm()'會給你你想要的嗎? – DonBoitnott

+0

@Sinatr - 該控件是我繪製DirectX調用的窗口。我試圖從一些不同的東西中獲取父窗體的最大化/恢復,調整大小,移動和鼠標事件,例如:只要鼠標在控件上,鼠標滾輪縮放,無論控件是否具有焦點。 –

回答

0

我也需要這個在我自己的自定義控件中。 我subclassed一個按鈕,並在onclick我需要知道的形式。 所以訣竅實際上不是在負載中獲取表單,而是在需要時獲取表單。

這爲我工作:

private Form GetParentForm(Control parent) 
{ 
    Form Result = parent as Form; 
    if (Result == null) 
    { 
     if (parent != null) 
     { 
      // Recursive is cool 
      return GetParentForm(parent.Parent); 
     } 
    } 
    return Result; 
} 

我使用這樣的

protected override void OnClick(EvnetArgs e) 
{ 
    Form form = GetParentForm(Parent); 
    if (form != null) 
    { 
     // do stuff here 
    } 
} 
+0

這基本上是FindForm的功能,對吧?正如我在我的文章中所描述的那樣,問題實際上是在ctor或ParentChanged事件期間父表單尚未設置,MSDN表示Load事件可能不是這種邏輯的好地方,因爲如何它處理MDI兒童。 –

+0

這就是爲什麼我說這個技巧是在你需要的時候得到表單,而不是在加載控件的時候。我不記得的細節了,但我有findform方法的麻煩,並取而代之的是這個小方法,不記得它是什麼了 – GuidoG

+0

我記得當用戶控件在繼承的mdi窗體上時,FindForm遇到了麻煩。由於一些黑暗的原因,它返回null,而我的方法並不奇怪,因爲它們基本上做同樣的事情。 – GuidoG