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
Hide Form Instead of Closing When Close Button Clicked
Exporting Datagridview to CSV File
How to Recognize If a String Contains Unicode Chars
Is a Reference Assignment Threadsafe
Can You Compile C# So It Doesn't Need the .Net Framework at Runtime
C# Code to Linkify Urls in a String
Sqlexception:String or Binary Data Would Be Truncated
Difference Between the Keydown Event, Keypress Event and Keyup Event in Visual Studio
Date Difference in Years Using C#
How to Determine If an Event Is Already Subscribed
How to Convert Percentage String to Double
Async Await VS Getawaiter().Getresult() and Callback
Does Reactive Extensions Support Rolling Buffers