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

时间:2022-09-26 10:09:34

I'm trying to create a method to simply clear all textboxes in a webform.

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

This is the code I'm calling:

这是我正在调用的代码:

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

It doesn't error, just never gets to call textBox.Text = string.Empty;

它没有错误,只是永远不会调用textBox.Text = string.Empty;

I'm guessing the list of textboxes has not been created and suspect I'm missing an important step. I reckon there is something wrong with Controls.OfType<TextBox>()

我猜测文本框列表尚未创建,并怀疑我错过了一个重要的步骤。我认为Controls.OfType ()有问题

I also tried using the following:

我也试过使用以下内容:

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

Again it didn't error but never called ClearTextBox.

它再次没有错误,但从未调用过ClearTextBox。

I know it's a c# schoolboy error and to be honest the penny hasn't dropped as to what IEnumerable is actually doing. Any help would be appreciated.

我知道这是一个c#schoolboy错误,说实话,penny还没有删除IEnumerable实际上在做什么。任何帮助,将不胜感激。

4 个解决方案

#1


2  

I think below will help you.It get the all textbox in IEnumerable as per your requirement.

我认为下面会帮助你。它可以根据你的要求获得IEnumerable中的所有文本框。

Calling Part

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

Function

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

#2


1  

The Controls property only starts at the top. You need to recursively step through each control and it's children to find all the textboxes:

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

#3


1  

Derivation of Josh's answer using Generics.

使用泛型来推导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;
    }
}

#4


1  

The issue is that you're not traversing the entire control's tree. You're just getting the direct children. You can write a simple method to get all of the children through the entire control's tree, plug that into your code, and it'll work.

问题是你没有遍历整个控件的树。你刚刚得到直接的孩子。您可以编写一个简单的方法来让所有孩子通过整个控件的树,将其插入到您的代码中,并且它将起作用。

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

Using this method you can now write:

使用此方法,您现在可以编写:

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

We can even generalize this to a Traverse method that isn't specific to Control, and that is capable of traversing any tree:

我们甚至可以将它推广到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);
    }
}

In this case, this would be called as Traverse(this, c => c.Controls), but has the benefit of being usable with any other type of tree.

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

#1


2  

I think below will help you.It get the all textbox in IEnumerable as per your requirement.

我认为下面会帮助你。它可以根据你的要求获得IEnumerable中的所有文本框。

Calling Part

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

Function

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

#2


1  

The Controls property only starts at the top. You need to recursively step through each control and it's children to find all the textboxes:

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

#3


1  

Derivation of Josh's answer using Generics.

使用泛型来推导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;
    }
}

#4


1  

The issue is that you're not traversing the entire control's tree. You're just getting the direct children. You can write a simple method to get all of the children through the entire control's tree, plug that into your code, and it'll work.

问题是你没有遍历整个控件的树。你刚刚得到直接的孩子。您可以编写一个简单的方法来让所有孩子通过整个控件的树,将其插入到您的代码中,并且它将起作用。

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

Using this method you can now write:

使用此方法,您现在可以编写:

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

We can even generalize this to a Traverse method that isn't specific to Control, and that is capable of traversing any tree:

我们甚至可以将它推广到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);
    }
}

In this case, this would be called as Traverse(this, c => c.Controls), but has the benefit of being usable with any other type of tree.

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