2013-04-01 32 views
1

我有一個UserControl有幾個子女UserControl和那些UserControl的孩子UserControl的。如何找到實現一個接口和調用方法的所有對象

考慮一下:

MainUserControl 
    TabControl 
    TabItem 
     UserControl 
     UserControl 
      UserControl : ISomeInterface 
    TabItem 
     UserControl 
     UserControl 
      UserControl : ISomeInterface 
    TabItem 
     UserControl 
     UserControl 
      UserControl : ISomeInterface 
    TabItem 
     UserControl 
     UserControl 
      UserControl : ISomeInterface 

這是我到目前爲止,但沒有發現任何ISomeInterface

PropertyInfo[] properties = MainUserControl.GetType().GetProperties(); 
foreach (PropertyInfo property in properties) 
{ 
    if (typeof(ISomeInterface).IsAssignableFrom(property.PropertyType)) 
    { 
     property.GetType().InvokeMember("SomeMethod", BindingFlags.InvokeMethod, null, null, null); 
    } 
} 

是否有可能因此發現所有的孩子UserControl的從實現ISomeInterfaceMainUserControl通過反射並在該界面上調用方法(void SomeMethod())?

+2

爲什麼你認爲的GetProperties()方法將遞歸下去?您正在枚舉該類型的屬性,而不是整個控件層次結構。考慮枚舉Controls集合。 –

回答

4

您將需要遞歸遍歷MainUserControl中的所有子控件。

這裏有一個輔助方法,你可以使用:

/// <summary> 
/// Recursively lists all controls under a specified parent control. 
/// Child controls are listed before their parents. 
/// </summary> 
/// <param name="parent">The control for which all child controls are returned</param> 
/// <returns>Returns a sequence of all controls on the control or any of its children.</returns> 

public static IEnumerable<Control> AllControls(Control parent) 
{ 
    if (parent == null) 
    { 
     throw new ArgumentNullException("parent"); 
    } 

    foreach (Control control in parent.Controls) 
    { 
     foreach (Control child in AllControls(control)) 
     { 
      yield return child; 
     } 

     yield return control; 
    } 
} 

然後:

foreach (var control in AllControls(MainUserControl)) 
{ 
    PropertyInfo[] properties = control.GetType().GetProperties(); 
    ... Your loop iterating over properties 

或(好得多,如果這會爲你工作,因爲它是一個簡單多了):

foreach (var control in AllControls(MainUserControl)) 
{ 
    var someInterface = control as ISomeInterface; 

    if (someInterface != null) 
    { 
     someInterface.SomeMethod(); 
    } 
} 

或者,使用Linq(需要一個using System.Linq來做到這一點):

foreach (var control in AllControls(MainUserControl).OfType<ISomeInterface>()) 
    control.SomeMethod(); 

這似乎是最好的。 :)

+2

也許你可以使用'is'運算符來添加。 OP似乎是在使用反射的方向,而動態鑄造更容易(也更便宜)(或者我也錯過了什麼?) – bas

+0

好點 - 我關注的是遞歸控制。 –

+0

是的,那就是我的意思。已經upvoted,但虛+ 2然後:) – bas

2

也許我在找錯方向自己。我的意思與馬修斯回答評論是:

foreach (var control in AllControls(MainUserControl)) 
{ 
    if (control is ISomeInterface) 
    { 

    } 
} 

foreach (var control in AllControls(MainUserControl)) 
{ 
    var someInterface = control as ISomeInterface; 
    if (someInterface != null) 
    { 
      someInterface.SomeMethod(); 
    } 
} 
+1

同意,我按照你的建議添加了它。 :) –

相關問題