Мне нужно получить все элементы управления в форме типа x. Я почти уверен, что однажды видел этот код, который использовал что-то вроде этого:
dim ctrls() as Control
ctrls = Me.Controls(GetType(TextBox))
Я знаю, что могу перебрать все элементы управления, получая детей с помощью рекурсивной функции, но Есть ли что-то более простое или более простое, например, как показано ниже?
Dim Ctrls = From ctrl In Me.Controls Where ctrl.GetType Is Textbox
Вот вам еще один вариант. Я протестировал его, создав образец приложения, а затем поместил GroupBox и GroupBox в исходный GroupBox. Внутри вложенного GroupBox я поместил 3 элемента управления TextBox и кнопку. Это код, который я использовал (даже включает рекурсию, которую вы искали)
public IEnumerable<Control> GetAll(Control control,Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl,type))
.Concat(controls)
.Where(c => c.GetType() == type);
}
Чтобы протестировать его в событии загрузки формы, мне нужно было подсчитать количество всех элементов управления внутри исходного GroupBox
private void Form1_Load(object sender, EventArgs e)
{
var c = GetAll(this,typeof(TextBox));
MessageBox.Show("Total Controls: " + c.Count());
}
И он каждый раз возвращал правильный счет, так что я думаю, что это сработает идеально для того, что вы ищете :)
Это может сработать:
Public Function getControls(Of T)() As List(Of T)
Dim st As New Stack(Of Control)
Dim ctl As Control
Dim li As New List(Of T)
st.Push(Me)
While st.Count > 0
ctl = st.Pop
For Each c In ctl.Controls
st.Push(CType(c, Control))
If c.GetType Is GetType(T) Then
li.Add(CType(c, T))
End If
Next
End While
Return li
End Function
Я думаю, что функция получения всех элементов управления, о которых вы говорите, доступна только для WPF .
В C # (поскольку вы пометили его как таковой) вы можете использовать выражение LINQ, подобное этому:
List<Control> c = Controls.OfType<TextBox>().Cast<Control>().ToList();
Редактировать для рекурсии:
В этом примере вы сначала создаете список элементов управления а затем вызовите метод для его заполнения. Поскольку метод рекурсивен, он не возвращает список, а просто обновляет его.
List<Control> ControlList = new List<Control>();
private void GetAllControls(Control container)
{
foreach (Control c in container.Controls)
{
GetAllControls(c);
if (c is TextBox) ControlList.Add(c);
}
}
Это можно сделать в одном операторе LINQ с помощью функции Descendants
, хотя я с ней не так хорошо знаком. См. на этой странице для получения дополнительной информации.
Отредактируйте 2, чтобы вернуть коллекцию:
Как предложил @ProfK, метод, который просто возвращает желаемые элементы управления, вероятно, является лучшей практикой. Чтобы проиллюстрировать это, я изменил код следующим образом:
private IEnumerable<Control> GetAllTextBoxControls(Control container)
{
List<Control> controlList = new List<Control>();
foreach (Control c in container.Controls)
{
controlList.AddRange(GetAllTextBoxControls(c));
if (c is TextBox)
controlList.Add(c);
}
return controlList;
}
Для этого можно использовать запрос LINQ. Это будет запрашивать все в форме типа TextBox
var c = from controls in this.Controls.OfType<TextBox>()
select controls;