2010-02-05 2 views
13

Existed MyControl1.Controls.OfType<RadioButton>() ищет только через первоначальную коллекцию и не входит в число детей.Найти все дочерние элементы управления определенного типа с помощью Enumerable.OfType <T>() или LINQ

Возможно ли найти все дочерние элементы управления определенного типа с использованием Enumerable.OfType<T>() или LINQ без написания собственного рекурсивного метода? Мне нравится this.

ответ

40

Я использую метод расширения, чтобы сгладить иерархию управления, а затем применить фильтры, чтобы использовать собственный рекурсивный метод.

Метод выглядит следующим образом

public static IEnumerable<Control> FlattenChildren(this Control control) 
{ 
    var children = control.Controls.Cast<Control>(); 
    return children.SelectMany(c => FlattenChildren(c)).Concat(children); 
} 
+1

Не могли бы вы привести пример кода? – abatishchev

+1

уверен, добавлен код –

+1

Действительно хороший фрагмент кода, спасибо за обмен! –

1

Для улучшения над ответом было бы целесообразно, чтобы изменить тип возвращаемого значения

//Returns all controls of a certain type in all levels: 
public static IEnumerable<TheControlType> AllControls<TheControlType>(this Control theStartControl) where TheControlType : Control 
{ 
    var controlsInThisLevel = theStartControl.Controls.Cast<Control>(); 
    return controlsInThisLevel.SelectMany(AllControls<TheControlType>).Concat(controlsInThisLevel.OfType<TheControlType>()); 
} 

//(Another way) Returns all controls of a certain type in all levels, integrity derivation: 
public static IEnumerable<TheControlType> AllControlsOfType<TheControlType>(this Control theStartControl) where TheControlType : Control 
{ 
    return theStartControl.AllControls().OfType<TheControlType>(); 
} 
1

Я использую Этот общий рекурсивный метод:

предположение о том, этого метода заключается в том, что если элемент управления T, чем метод не смотрит в его дочерние элементы. Если вам нужно также посмотреть на своих детей, вы можете легко изменить его соответствующим образом.

public static IList<T> GetAllControlsRecusrvive<T>(Control control) where T :Control 
{ 
    var rtn = new List<T>(); 
    foreach (Control item in control.Controls) 
    { 
     var ctr = item as T; 
     if (ctr!=null) 
     { 
      rtn.Add(ctr); 
     } 
     else 
     { 
      rtn.AddRange(GetAllControlsRecusrvive<T>(item)); 
     } 

    } 
    return rtn; 
}