ignore hidden empty textboxes - c#

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

Related

How can I change the properties of controls in all tabs in Windows Forms Application?

I have been searching for this answer for a while with no luck. It seems like a fairly simple question but I can't come up with anything, so here goes:
I want to set all the controls in all of my tabs to ReadOnly = true or Enabled = false (or the reverse).
I'm using this code:
public void readOnly(bool read)
{
if (read == true)
{
foreach (var c in mainTab.Controls)
{
if (c is TextBox)
{
((TextBox)c).ReadOnly = true;
}
if (c is CheckBox)
{
((CheckBox)c).Enabled = false;
}
Etc. ......
How can I apply changes to all tabs, not just mainTab, without repeating the code? I'm new to programming so I apologize if I'm missing something obvious...
If this question has already been answered could you kindly point me to the page?
To access all tabs, you can use the TabPages property of the TabControl. Further, you can significantly simplify your code:
public void SetReadOnly(bool readOnly)
{
foreach (TabPage tab in tabControl.TabPages)
{
foreach (Control c in tab.Controls)
{
if (c is TextBox)
{
((TextBox)c).ReadOnly = readOnly;
}
else
{
// All controls support this property
c.Enabled = !readOnly;
}
}
}
}
You could create a method that will loop through the controls of each tab page in your tab control and set the Enabled property of the controls, and have a Boolean argument that says what the value should be:
private void SetTabControlEnabled(bool enabled)
{
foreach (TabPage tabPage in tabControl1.TabPages)
{
foreach (Control control in tabPage.Controls)
{
control.Enabled = enabled;
}
}
}
Then, as an example, you could call this method and pass true to enable the controls or false to disable them:
private void btnEnable_Click(object sender, EventArgs e)
{
SetTabControlEnabled(true);
}
private void btnDisable_Click(object sender, EventArgs e)
{
SetTabControlEnabled(false);
}
You need a recursive function:
public static void EnabledDisabeldControls(System.Windows.Forms.Control.ControlCollection paramControls, bool enabled)
{
foreach (System.Windows.Forms.Control c in paramControls)
{
if (c is TextBox)
{
((TextBox)c).ReadOnly = !enabled;
}
if (c is CheckBox)
{
((CheckBox)c).Enabled = enabled;
}
EnabledDisabeldControls(c.Controls, enabled);
}
}

Unable to cast object of Type1 to type Type2?

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

radiobuttons - test if checked - why do first 2 approaches fail?

I was wondering why below did not work as expected...
if if-statement changed to (!ctrl.checked) it returns all radio-button's names)
myForm f = new myForm();
foreach (RadioButton ctrl in f.Controls.OfType<RadioButton>())
{
if (ctrl.Checked)
MessageBox.Show(ctrl.Name);
}
I also tried
foreach (Control c in f.controls)
if (c is radiobutton)
{
if (c.Checked)
{
messagebox.show(c.name);
}
when I then put all radio-buttons in a group-box and used below code:
foreach (RadioButton c in groupBox1.Controls)
{
if (c.Checked)
{
MessageBox.Show(c.Name);
}
}
it worked fine.
what's the difference here.
any help appreciated
I'm guessing that your radio button is the child of a control other than the form. You need to recursively search for the radio buttons.
public void DisplayRadioButtons()
{
Form f = new Form();
RecursivelyFindRadioButtons(f);
}
private static void RecursivelyFindRadioButtons(Control control)
{
foreach (Control childControl in control.Controls)
{
RecursivelyFindRadioButtons(childControl);
if (childControl is RadioButton && ((RadioButton) childControl).Checked)
{
MessageBox.Show(childControl.Name);
}
}
}

How to hide all text boxes if they are empty

I'm just wondering really.
I have series of if statements that check
if textboxes are empty (or have results strings) after i pass SQL
results to then
.
if (IncidentData.Tables[0].Rows[0]["Property Category"].ToString()
== "RoadVehicle")
{
lbl_alarmOperated.Visible = false; tb_alarmOperated.Visible = false;
}
else
{
lbl_alarmOperated.Visible = true;
tb_alarmOperated.Visible = true;
}
I have been looking into controls and seeing if i can do a check on all textboxes and hide them if they are empty (instead of writing loads of if statements)
i have this at the moment:
public void ChecknHide()
{
HideTextBoxes(this);
}
protected void HideTextBoxes(Control ctrl)
{
foreach (var c in ctrl.Controls)
{
if (c is TextBox) ((TextBox)c).Text = String.Empty;
{
((TextBox)c).Visible = false;
}
}
}
Its mostly put together from reading posts on here. But I've ran into an issue. When i compile and go to view the page i get this:
Unable to cast object of type 'ASP.masterpage_master' to type
'System.Web.UI.WebControls.TextBox'.
Any ideas whats going wrong?
The statement after the if isn't part of the condition. This causes all controls to be casted to a TextBox. You should be able to fix it like so:
protected void HideTextBoxes(Control ctrl)
{
foreach (var c in ctrl.Controls)
{
if (c is TextBox && ((TextBox)c).Text == String.Empty)
{
((TextBox)c).Visible = false;
}
}
}
Weird code line:
if (c is TextBox) ((TextBox)c).Text = String.Empty;
Try something like:
protected void HideTextBoxes(Control ctrl)
{
//Iterate over controlls
foreach (var c in ctrl.Controls)
{
//Check for Textbox controls with the .Text property equal to Null or Empty.
if (c is TextBox && string.IsNullOrEmpty(((TextBox)c).Text))
{
//Set visibility of Textbox control to invisible.
((TextBox)c).Visible = false;
}
}
}
You're checking if c is a TextBox, but then trying to cast c as a TextBox and set it to String.Empty in the same line, regardless of whether it actually is a TextBox.
if (c is TextBox) ((TextBox)c).Text = String.Empty;

How to check multiple combo-box value is Empty or Not

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

Categories

Resources