2013-04-01 2 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); 
    } 
} 

이 가능하므로 ISomeInterface을 구현 MainUserControl에서 모든 자식 UserControl의 내용을 알아보십시오

이 고려 리플렉션을 통해 해당 인터페이스에서 메소드 (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

동의, 나는 당신의 제안에 따라 그것을 추가했다. :) –

관련 문제