Foreach Control in Form, How to Do Something to All the Textboxes in My Form

Foreach Control in form, how can I do something to all the TextBoxes in my Form?

You're looking for

foreach (Control x in this.Controls)
{
if (x is TextBox)
{
((TextBox)x).Text = String.Empty;
}
}

Selecting all textboxes in foreach and editing them.. Not working

The problem lies in this statement:

Btw, my winform has 12 textboxes. 4 each in 3 different groupboxes.

Which means your form does not have those TextBox controls as direct children. Thus, using Controls.OfType will return no items. You can confirm that by setting a breakpoint in the foreach. You won't hit it (unless there is some other text box you aren't telling us about).

There are many approaches, the easy one would be to just nest your foreach's:

foreach (GroubBox g in Control.OfType<GroupBox>())
{
foreach (TextBox a in g.Controls.OfType<TextBox>())
{
a.Text = "";
}
}

Or you could search the control tree recursively. This has the advantage of working in the general case. It is discussed at: How to get ALL child controls of a Windows Forms form of a specific type (Button/Textbox)?

Foreach loop through controls that are textbox doesn't return

When you call Control.Controls, it will only return the controls at the outermost level. It won't recursively descend into any container controls that hold other controls.

If your controls are in another container, you will need to use that container's .Controls property instead.

Alternatively you can generalize it by writing a method to recursively return all the controls from the parent and all it's children, like so:

public IEnumerable<Control> AllControls(Control container)
{
foreach (Control control in container.Controls)
{
yield return control;

foreach (var innerControl in AllControls(control))
yield return innerControl;
}
}

You can then use that instead of Control.Controls as follows:

private void test() // Assuming this is a member of a Form other class derived from Control
{
var textboxesWithFilledTag =
AllControls(this).OfType<TextBox>()
.Where(tb => (string) tb.Tag == "Filled");

foreach (var textbox in textboxesWithFilledTag)
Debug.WriteLine(textbox.Text);
}

As the comment says, I'm assuming that the test() method is a member of your Form or another class derived from Control. If it isn't, you will have to pass the parent control to it:

private void test(Control container)
{
var textboxesWithFilledTag =
AllControls(container).OfType<TextBox>()
.Where(tb => (string) tb.Tag == "Filled");

foreach (var textbox in textboxesWithFilledTag)
Debug.WriteLine(textbox.Text);
}

The following method has identical results to the one above, for reference (and is more readable IMHO):

private void test(Control container)
{
foreach (var textbox in AllControls(container).OfType<TextBox>())
if ((string)textbox.Tag == "Filled")
Debug.WriteLine(textbox.Text);
}

For your code, your button click handler might look something like this:

void button1_Click(object sender, EventArgs e)
{
foreach (var c in AllControls(this).OfType<TextBox>())
{
if ((string) c.Tag == "Filled")
{
// Here is where you put your code to do something with Textbox 'c'
}
}
}

Note that you also need the AllControls() method, of course.

Get all textboxes of an form with their name in ascending order

You can use LINQ to get all sorted by name text boxes:

var allTexboxes = this.Controls.OfType<TextBox>();
var sortedTextBoxes = allTexboxes
.Where(i => String.IsNullOrEmpty(i.Text))
.OrderBy(i => i.Name)
.ToArray();

Then you can get name by this way:

var name = sortedTextBoxes[0].Name;

If you want just names as string array:

var allTexboxes = this.Controls.OfType<TextBox>();
var sortedNames = allTexboxes
.Where(i => String.IsNullOrEmpty(i.Text))
.OrderBy(i => i.Name)
.Select(i => i.Name)
.ToArray();

and to get name:

var name = sortedNames[0];

Assigning event TextChanged to all textboxes in Form

You can make your method recursive:

private void Form1_Load(object sender, EventArgs e)
{
Assign(this);
}

void Assign(Control control)
{
foreach (Control ctrl in control.Controls)
{
if (ctrl is TextBox)
{
TextBox tb = (TextBox)ctrl;
tb.TextChanged += new EventHandler(tb_TextChanged);
}
else
{
Assign(ctrl);
}
}
}

void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Tag = "CHANGED"; // or whatever
}

Just find a better name for the method instead of Assign.

loop over all textboxes in a form, including those inside a groupbox

You can use this function, linq might be a more elegant way.

Dim allTxt As New List(Of Control)
For Each txt As TextBox In FindControlRecursive(allTxt, Me, GetType(TextBox))
'....'
Next

Public Shared Function FindControlRecursive(ByVal list As List(Of Control), ByVal parent As Control, ByVal ctrlType As System.Type) As List(Of Control)
If parent Is Nothing Then Return list
If parent.GetType Is ctrlType Then
list.Add(parent)
End If
For Each child As Control In parent.Controls
FindControlRecursive(list, child, ctrlType)
Next
Return list
End Function

How do I loop through all textboxes and make them run corresponding actions from action dictionary?

Assuming I understand the question correctly, here's my answer to the interpretation of the question

private void Form1_Load(object sender, EventArgs e)
{
foreach (TextBox tb in this.Controls.OfType<TextBox>())
{
tb.Enter += new EventHandler(textBoxAll_Enter);
tb.Leave += new EventHandler(textBoxAll_Leave);
}
}

private void textBoxAll_Enter(object sender, EventArgs e)
{
((TextBox)sender).Text = "textbox gained focus";
}

private void textBoxAll_Leave(object sender, EventArgs e)
{
((TextBox)sender).Text = "textbox lost focus";
}


Related Topics



Leave a reply



Submit