Domoq
Domoq

Reputation: 25

Foreach iteration not iterating through textboxes

I have made a method to check all of my textboxes and tell me if any are empty. When I debug it and follow through the code it just completely skips over the foreach loop.

Here is my code:

private bool checkSolved()
{
    bool isSolved = true; //Solve Variable
    foreach (TextBox tb in this.Controls.OfType<TextBox>()) //Iterates through all textboxes
    {
       if (tb.Text == null) //Checks to see if one of them is null
       {
          isSolved = false; //Sets bool to false
       }
    }
    return isSolved; //Returns bool
}

Upvotes: 0

Views: 229

Answers (3)

Tim Schmelter
Tim Schmelter

Reputation: 460298

You need a recursive search. Also, TextBox.Text never returns null, the property returns "" instead. This extension returns all controls of a given type lazily:

public static IEnumerable<T> GetChildControlsRecursive<T>(this Control root) where T: Control
{
    if (root == null) throw new ArgumentNullException("root");
    var stack = new Stack<Control>();
    stack.Push(root);
    while (stack.Count > 0)
    {
        Control parent = stack.Pop();
        foreach (Control child in parent.Controls)
        {
            if (child is T)
                yield return (T) child;
            stack.Push(child);
        }
    }
    yield break;
}

Now you can use this code to check if all TextBoxes have text:

var textBoxes = this.GetChildControlsRecursive<TextBox>();
bool isSolved = textBoxes.All(txt => !string.IsNullOrEmpty(txt.Text));

Upvotes: 2

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73502

TextBox.Text will never be null. You need to compare it against Empty. Use string.IsNullOrEmpty method.

if (string.IsNullOrEmpty(tb.Text))
{

}

If it doesn't execute the loop at all then your Controls collection doesn't have any TextBox in it.

Edit1: Some hints to debug:

If you can't manage to get this work, most probably your Textboxes will not be parented by this(your control here). It will have been added to some other parent instead. It could be Panel or GroupBox etc. In that case accessing this.Controls is not useful you need to access respectiveParent.Controls collection. You do it like this recursively.

Upvotes: 0

Emran Sadeghi
Emran Sadeghi

Reputation: 612

    public static List<T> GetAllControlsInside<T>(Control control)
    {
        List<Control> result = new List<Control>();
        GetAllControlsInside<T>(control, result);
        return result.OfType<T>().ToList();
    }

    private static void GetAllControlsInside<T>(Control control, List<Control> result)
    {
        foreach (Control ctrl in control.Controls)
        {
            result.Add(ctrl);
            if (ctrl.HasChildren && !(ctrl is T))
            {
                GetAllControlsInside<T>(ctrl, result);
            }
        }
    }


private bool checkSolved()
{
    bool isSolved = true; //Solve Variable
    foreach (TextBox tb in GetAllControlsInside<TextBox>(this)) //Iterates through all textboxes
    {
       if (String.IsNullOrEmpty(tb.Text)) //Checks to see if one of them is null
       {
          isSolved = false; //Sets bool to false
       }
    }
    return isSolved; //Returns bool
}

Upvotes: 0

Related Questions