2014-02-04 2 views
0

Я пытаюсь создать метод, чтобы просто очистить все текстовые поля в веб-форме.Looping Through Textboxes Использование IEnumerable Not Working

Это код, который я звоню:

private void clearFrom() 
{ 
    IEnumerable<TextBox> textBoxes = Controls.OfType<TextBox>(); 
    foreach (TextBox textBox in textBoxes) 
    { 
     textBox.Text = string.Empty; 
    } 
} 

Это не ошибка, просто никогда не будет называть textBox.Text = string.Empty;

Я предполагаю, что список текстовых полей не был создан и подозреваемый Я пропустил важный шаг. Я думаю, есть что-то не так с Controls.OfType<TextBox>()

Я также попытался использовать следующее:

private void clearFrom() 
{ 
    IEnumerable<TextBox> Textboxes = (from Control c in this.Controls 
             where c.GetType() == typeof(TextBox) 
             select c).AsEnumerable().Cast<TextBox>(); 
    FunctionalExtensions.ForEach(Textboxes, ClearTextBox); 
} 

public static class FunctionalExtensions 
{ 
    public static void ForEach<T>(IEnumerable<T> items, Action<T> DoSomething) 
    { 
     foreach (T item in items) 
     { 
      DoSomething(item); 
     } 
    } 
} 

private void ClearTextBox(TextBox txtbox) 
{ 
    txtbox.Text = string.Empty; 
} 

Опять не ошибка, но никогда не называли ClearTextBox.

Я знаю, что это ошибка школьника C#, и, честно говоря, ни копейки не упали, как это делает IEnumerable. Любая помощь будет оценена по достоинству.

+2

Пробовал ли вы отлаживать программу? – Matt

+0

Да, насколько я мог видеть, что текстовые поля не были выбраны в коллекцию. – ComfortablyNumb

+0

@ Josh/@ Servy/@ DigitalD Спасибо всем за ваши предложения и образцы. Пенни - это своего рода падение! – ComfortablyNumb

ответ

2

Я думаю, что ниже, поможет you.It получить все текстовое поле в IEnumerable согласно вашему требованию.

Вызов Часть

var c = GetAll(this, typeof(TextBox)); 
     foreach (TextBox txt in c) 
     { 
      txt.Text = ""; 
     } 

Функция

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); 
    } 
+0

Love LINQ. Хороший код чувак. Так держать. 1000 баллов за u .. :) –

+0

Благодарим за помощь. Я был в правильном месте! Я не использовал LINQ.Довольно расклеивающий материал. – ComfortablyNumb

1

Свойство Controls начинается только сверху. Вам нужно рекурсивно пройти через каждый элемент управления, и это дети, чтобы найти все текстовые поля:

public static List<Control> GetAllControls(List<Control> controls, Type t, Control parent /* can be Page */) 
{ 
foreach (Control c in parent.Controls) 
{ 
if (c.GetType()== t) 
controls.Add(c); 
if (c.HasControls()) 
controls = GetAllControls(controls, t, c); 
} 
return controls; 
} 
+0

Вот поток SO, который объясняет это более подробно: http://stackoverflow.com/questions/4955769/better-way-to-find-control-in-asp-net –

1

Вывод ответа Джоша с помощью дженериков.

public static IEnumerable<T> GetAllControlsOfType<T>(Control parent) where T: Control { 
    foreach (Control c in parent.Controls) { 
     if (c is T) 
      yield return c as T; 
     if (c.HasControls()) 
      foreach (T innerControl in GetAllControlsOfType<T>(c)) 
       yield return innerControl; 
    } 
} 
+0

Рекурсивные блоки итераторов довольно неэффективны. Блоки итератора и конечный автомат, созданный для их представления, добавят немного больше накладных расходов, чем «обычные» вызовы методов. Стоит использовать явный стек для перемещения дерева при работе с блоками итератора. – Servy

+0

Этого легко изменить. Я добавлю более эффективный пример. –

1

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

public static IEnumerable<Control> GetAllChildren(this Control root) 
{ 
    var stack = new Stack<Control>(); 
    stack.Push(root); 

    while (stack.Any()) 
    { 
     var next = stack.Pop(); 
     foreach (Control child in next.Controls) 
      stack.Push(child); 
     yield return next; 
    } 
} 

Используя этот метод, теперь вы можете написать:

private void clearFrom() 
{ 
    var textBoxes = this.GetAllChildren().OfType<TextBox>(); 
    foreach (TextBox textBox in textBoxes) 
    { 
     textBox.Text = string.Empty; 
    } 
} 

Мы можем даже обобщить это на Traverse метод, который не относится к Control, и который способен обходу любого дерева:

В этом случае это будет называться Traverse(this, c => c.Controls), но имеет преимущество использования любого другого типа дерева.

+0

Благодарим за предложение – ComfortablyNumb