I am having 40 combo-box in my win-form application, I want to check at end on button click that all the combo-box value has been entered i.e no combo-box value has been selected empty
i am trying below code using for each loop but cant find success
foreach (Control c in this.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue==string.Empty)
{
MessageBox.Show("please fill all fields");
}
}
}
so how to achieve this validation in simple lines of codes
Try to use linq and a recursion:
var isAnyEmpty = ScanForControls<ComboBox>(this)
.Where(x => x.SelectedIndex < 0)
.Any();
if (isAnyEmpty)
MessageBox.Show("please fill all fields");
And recursion search:
public IEnumerable<T> ScanForControls<T>(Control parent) where T : Control
{
if (parent is T)
yield return (T)parent;
foreach (Control child in parent.Controls)
{
foreach (var child2 in ScanForControls<T>(child))
yield return (T)child2;
}
}
To make sure that you check each & every ComboBox in your Form you will have to iterate over each control in you Form, Try this for that.
private void button1_Click(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue == null)
{
MessageBox.Show("please fill all fields");
break;
}
}
else
recursiveComboboxValidator(c);
}
}
void recursiveComboboxValidator(Control cntrl)
{
foreach (Control c in cntrl.Controls)
{
if (c is ComboBox)
{
ComboBox textBox = c as ComboBox;
if (textBox.SelectedValue == null)
{
MessageBox.Show("please fill all fields");
break;
}
}
else
recursiveComboboxValidator(c);
}
}
Related
Quick update, i found out why the code wont work, all the textboxes i want to check are in groupboxes and thats the problem, if i remove the groupbox the problem is resolved.
Is there a way around this ?
Found the solution.
Posted below for future reference.
Thanks again for all your imput.
foreach (var textBox in Controls.OfType<GroupBox>().SelectMany(groupBox => groupBox.Controls.OfType<TextBox>()))
{
if (textBox is TextBox && textBox.Visible && string.IsNullOrEmpty(textBox.Text))
{
MessageBox.Show($"Missing {textBox.Name} value!");
Focus();
return;
}
}
Have you thought of using a foreach of the form's controls instead? Something like:
foreach (Control c in Controls)
{
if (c is TextBox && c.Visible && string.IsNullOrEmpty(c.Text))
{
MessageBox.Show($"TextBox {c.Name} is empty");
}
}
EDIT: If your form contains groupboxes, groupboxes are groups of controls so you will have to iterate through their controls with a sub-foreach too. Here's how:
private void Form1_Load(object sender, EventArgs e)
{
CheckControlCollection(this.Controls);
}
private void CheckControlCollection(Control.ControlCollection cc)
{
foreach (Control c in cc)
if (c is GroupBox)
CheckControlCollection(c.Controls);
else
CheckControl(c);
}
private void CheckControl(Control c)
{
if (c is TextBox && c.Visible && string.IsNullOrEmpty(c.Text))
MessageBox.Show($"TextBox {c.Name} is empty");
}
This will make sure we don't get screwed by nested groupboxes
I am trying to validate a bunch of controls within a GroupBox in a form based application.
I cannot seem to map the ComboBox to the application for it to recognize and generate the error and it only does so for the TextBox.
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (Control control in groupBox1.Controls)
{
string controlType = control.GetType().ToString();
var lst = new List<string>() { "System.Windows.Forms.TextBox" ,"System.Windows.Forms.ComboBox"};
//if (controlType == "System.Windows.Forms.TextBox")
if (lst.Contains(controlType, StringComparer.OrdinalIgnoreCase))
{
TextBox txtBox = (TextBox)control;
ComboBox combo = (ComboBox)control;
if (string.IsNullOrEmpty(txtBox.Text) && string.IsNullOrEmpty(combo.Text))
{
MessageBox.Show(txtBox.Name + " Can not be empty");
}
}
}
}
Here is the error I am receiving:
Unable to cast object of type 'System.Windows.Forms.ComboBox' to type 'System.Windows.Forms.TextBox'.
In your code, it cast any textbox and any combo into a textbox AND a combo.
You need to cast it to what it is only.
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (Control control in groupBox1.Controls)
{
if (control is ComboBox)
{
ComboBox combo = (ComboBox)control;
if (string.IsNullOrEmpty(combo.Text)) MessageBox.Show(combo.Name + " Can not be empty");
}
else if (control is TextBox)
{
TextBox txtBox = (TextBox)control;
if (string.IsNullOrEmpty(txtBox.Text)) MessageBox.Show(txtBox.Name + " Can not be empty");
}
}
}
If the groupbox only have textbox and combobox you can also do:
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (dynamic control in groupBox1.Controls)
{
if (string.IsNullOrEmpty(control.Text)) MessageBox.Show(control.Name + " Can not be empty");
}
}
Let's summarize what you want to do:
For each control inside groupBox1
... of type TextBox or ComboBox
Validate that the control is not empty, if it is, show a message box
Here's some important points:
Every control that inherits from Control has a public Text property, you don't really need to know if it is a textbox or a combobox for this part
No control is both a textbox and a combobox (that is, no control class inherits from both TextBox and ComboBox), so one of those casts will fail every time
You could use as instead of the hard cast, which would return null in the cast of a cast that cannot be done, but with point 1. above this is not necessary
So here is the rewritten code with the above knowledge:
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (Control control in groupBox1.Controls)
{
if (!(control is TextBox || control is ComboBox))
continue;
if (!string.IsNullOrEmpty(control.Text))
continue;
MessageBox.Show(control.Name + " Can not be empty");
}
}
Note that if you want to do other things as well, which would need to know if the control is a textbox or a combobox, I would instead rewrite it as follows:
private void groupBox1_Validating(object sender, CancelEventArgs e)
{
foreach (Control control in groupBox1.Controls)
{
var textbox = control as TextBox;
if (textbox != null)
{
... do your processing of textboxes here
continue;
}
var combobox = control as ComboBox;
if (combobox != null)
{
... do your processing of comboboxes here
continue;
}
... do your processing of other controls here
}
}
Since you just want to check the Text and Name property and because the both TextBox and ComboBox inherits from Control class you don't need casting here. This should works for you:
foreach (Control control in groupBox1.Controls)
{
if (!lst.Contains(control.GetType().ToString(), StringComparer.OrdinalIgnoreCase)) continue;
if (string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text))
{
MessageBox.Show(control.Name + " Can not be empty");
}
}
Or with Linq:
foreach (Control control in from Control control in groupBox1.Controls
where lst.Contains(control.GetType().ToString(), StringComparer.OrdinalIgnoreCase)
where string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text)
select control)
{
MessageBox.Show(control.Name + " Can not be empty");
}
Use the is operator to check whether you have the right type:
if(control is TextBox)
{
TextBox txtBox = (TextBox)control;
// Do something with txtBox
if (string.IsNullOrEmpty(txtBox.Text))
{
MessageBox.Show(txtBox.Name + " Can not be empty");
}
}
if(control is ComboBox)
{
ComboBox combo = (ComboBox)control;
// Do something with combo
if (string.IsNullOrEmpty(combo.Text))
{
MessageBox.Show(combo.Name + " Can not be empty");
}
}
As #LasseV.Karlsen pointed out, I was taking the long route by individually adding in each control. I simply added control instead of something rather than specific controls.
Here is what my updated code looks like now:
foreach (Control control in groupBox1.Controls)
{
string controlType = control.GetType().ToString();
var lst = new List<string>() { "System.Windows.Forms.TextBox" ,"System.Windows.Forms.ComboBox"};
//if (controlType == "System.Windows.Forms.TextBox")
if (lst.Contains(controlType, StringComparer.OrdinalIgnoreCase))
{
// TextBox txtBox = (TextBox)control;
// ComboBox combo = (ComboBox)control;
if (string.IsNullOrEmpty(control.Text) && string.IsNullOrEmpty(control.Text))
{
MessageBox.Show(control.Name + " Can not be empty");
}
}
I'm trying to change the Text in my TextBoxes in a form but I can't find out how to account for all of my TextBoxes without doing them individually...
I've tried the following code; however, my int i returns 0.
int i = 0;
foreach (Control c in this.Controls)
{
if (c.GetType().ToString() == "System.Web.UI.WebControls.TextBox")
{
i++;
((TextBox)c).Text = CleanInput(((TextBox)c).Text);
}
}
I'm just confused on how to grab all of my TextBoxes and check them...
Try this:
int i = 0;
foreach (Control c in this.Controls)
{
if (c is TextBox)
{
i++;
((TextBox)c).Text = CleanInput(((TextBox)c).Text);
}
}
If all TextBoxes are not children of "this", use a recursive method:
CleanTextBoxes(this)
private void CleanTextBoxes(Control TheControl)
{
foreach (Control c in TheControl.Controls)
{
if (c is TextBox) ((TextBox)c).Text = CleanInput(((TextBox)c).Text);
else CleanTextBoxes(c) ;
}
}
I have a form which contains the following types of controls (only):
Button
ComboBox
Label
TextBox
I have a "Clear" button that calls this method:
private void ClearControls()
{
foreach (TextBox txtbx in this.Controls)
{
if (txtbx != null)
{
txtbx.Text = string.Empty;
}
}
foreach (ComboBox cmbx in this.Controls)
{
if (cmbx != null)
{
cmbx.SelectedIndex = -1;
}
}
}
...yet when I call it, the app hangs, and the log file says "Invalid cast" for that method. How could that be? It should deal with the TextBoxes and ComboBoxes, and disregard the rest - where could the invalid cast be?
That's not what foreach does.
Specifying a type in a foreach loop does not skip items of other types; instead, it will cast every item to that type.
You can call .OfType<T>() to get the filtered list that you're looking for.
The foreach will try to cast the control to the specified type which will give that invalid cast exception, what you should do is:
foreach(Control ctrl in this.Controls)
{
if(ctrl as TextBox != null)
{
//Textbox logic
}
if(ctrl as ComboBox!= null)
{
//ComboBox logic
}
}
Based on Gunther's starting point, this works:
foreach (Control ctrl in this.Controls)
{
if (ctrl as TextBox != null)
{
ctrl.Text = string.Empty;
}
if (ctrl as ComboBox != null)
{
((ComboBox)ctrl).SelectedIndex = -1;
}
}
I have a asp.net page which is inherited from a master page .I want to clear all controls in this page .I tried using the bellow method .This is not working if a master page is there. Otherwise its working fine any ideas?
private void ClearControls()
{
foreach(Control c in Page.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
try this:
public void FindAllTextBox(Control ctrl)
{
if (ctrl != null)
{
foreach (Control c in ctrl.Controls)
{
if (c is TextBox)
((TextBox)c).Text = string.empty;
FindAllTextBox(c);
}
}
}
Ex.:
Control ctrl = this.FindControl("content");
FindAllTextBox(ctrl);
You should be able to do this with Page.Form.FindControl("ContentPlaceHolder1").Controls:
foreach (Control item in Page.Form.FindControl("ContentPlaceHolder1").Controls)
{
if (item is TextBox)
{
((TextBox)item).Text = string.Empty;
}
}
This is probably because of your controls are inside of another container when you add a master page. Have you tried adding another foreach before if?
private void ClearControls()
{
foreach(Control container in Page.Controls)
{
foreach (Control c in container.Controls)
{
foreach (Control ctrl in c.Controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).Text = string.Empty;
}
}
}
}
}
I wouldn't do it this way though. Sometimes hardcoding is better. This would use a lot of resource when called on a page that contains lots of controls.
Don't hard code:
//Recursively get all the formControls underneath the current one, be it Page, UserControl or whatever.
public static IEnumerable<Control> GetAllControls(this Control parent)
{
foreach (Control control in parent.Controls)
{
yield return control;
foreach (Control descendant in control.GetAllControls())
{
yield return descendant;
}
}
}
Then you can call it in your webform / control:
var formCtls = this.GetAllControls().OfType<TextBox>();
foreach(TextBox txtbx in formCtls)
{
//do what you gotta do ;)
}
First, use operator as instead of is and cast:
TextBox tb = ctrl as TextBox;
if (tb != null)
{
tb.Text = String.Empty;
}
Second, you can use ITextControl instead of TextBox.
And third, try next extension method:
public static IEnumerable<T> GetChildControls(this Control control) where T : Control
{
var children = (control.Controls != null) ? control.Controls.OfType<T>() : Enumerable.Empty<T>();
return children.SelectMany(c => GetChildControls(c)).Concat(children);
}
Usage:
foreach (var c in this.Page.Controls.GetChildControls<TextBox>())
{
c.Text = String.Empty;
}
I had the same problem but I think I was making it too hard. I'm using an AJAX UpdatePanel control and I just referenced that instead of going all the way up to the MasterPage. This worked for me.
foreach (Control c in UpdatePanel1.Controls)
{
foreach (Control c1 in c.Controls)
{
if (c1 is TextBox)
{
TextBox txtBox = (TextBox)c1;
txtBox.Text = "0";
}
}
}
Just keep the controls in Panel, and try the code below
foreach (Control cntrl in pnl.Controls)//pnl is panel id
{
if (cntrl is TextBox)
{
TextBox txtBox = (TextBox)cntrl;
txtBox.Text = " ";
}
}
Make a method on your .cs like this:
//Where "this" is Page.
ClearInput(this);
private void ClearInput(Control parent)
{
foreach (Control c in parent.Controls)
{
if (c.Controls.Count > 0)
ClearInput(c);
else
{
if (c is TextBox)
(c as TextBox).Text = "";
if (c is CheckBox)
(c as CheckBox).Checked = false;
if (c is DropDownList)
(c as DropDownList).SelectedIndex = 1;
}
}
}
private void EnableControls(Control control)
{
var textbox = control as TextBox;
if (textbox != null)
{
textbox.Enabled = true;
}
var dropDownList = control as DropDownList;
if (dropDownList != null)
{
dropDownList.Enabled = true;
}
var radioButton = control as RadioButton;
if (radioButton != null)
{
radioButton.Enabled = true;
}
var checkBox = control as CheckBox;
if (checkBox != null)
{
checkBox.Enabled = true;
}
foreach (Control childControl in control.Controls)
{
EnableControls(childControl);
}
}
public void getAllCtl(ControlCollection ctls)
{
foreach (Control c in ctls)
{
if (c is System.Web.UI.WebControls.TextBox)
{
//TextBox tt = c as TextBox;
////to do something by using textBox tt.
((TextBox)c).Text = string.Empty;
}
if (c is System.Web.UI.WebControls.CheckBox)
{
((CheckBox)c).Checked = false;
}
if (c is System.Web.UI.WebControls.DropDownList)
{
((DropDownList)c).SelectedIndex = -1;
}
if (c.HasControls())
{
getAllCtl(c.Controls);
}
}
}
calling in aspx.cs file as
getAllCtl(this.Form.Controls);
This is OK and tested work for all Master-child page and where ever multiple controls are contains in the page...