使用IEnumerable无法正常运行文本框

时间:2014-02-04 17:07:39

标签: c# asp.net textbox

我正在尝试创建一种方法来简单地清除网络表单中的所有文本框。

这是我正在调用的代码:

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#schoolboy错误,说实话,一分钱还没有说明IEnumerable实际上在做什么。任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:2)

我认为以下内容对您有所帮助。它可以根据您的要求获得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);
    }

答案 1 :(得分: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;
}

答案 2 :(得分:1)

使用泛型来推导Josh的答案。

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;
    }
}

答案 3 :(得分: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特有的,并且能够遍历任何树:

public static IEnumerable<T> Traverse<T>(T item, Func<T, IEnumerable<T>> childSelector)
{
    var stack = new Stack<T>();
    stack.Push(item);
    while (stack.Any())
    {
        var next = stack.Pop();
        yield return next;
        foreach (var child in childSelector(next))
            stack.Push(child);
    }
}

在这种情况下,这将被称为Traverse(this, c => c.Controls),但具有可与任何其他类型的树一起使用的好处。