Is there any way to group input fields in win forms? - c#

For example if I want to check if all the input fields are filled, I do not want to do this with a lot of if statements, especially if there are a lot of text fields. So is there a better way?

What about looping through all controls in the form, and get if it's empty or not ?
foreach(Control control in this.Controls)
{
if(control is TextBox && control.Text == "")
{
MessageBox.Show("You have to fill all fields");
return;
}
}
sure you can check for whatever control you want ! not just the textBoxes

With System.Linq you can do it in one line, and filter it on the controls you need:
this.Controls.OfType<TextBox>().All(box => box.Text.Length > 0);
Or for checkbox
this.Controls.OfType<CheckBox>().All(box => box.Checked);
And so on.
It will return true if all is filled/checked.
Just remember to put using System.Linq; on top of your code

Related

How to exclude a particular kind of control from a foreach loop?

I am attempting to validate a forms controls to see if they are empty and found an interesting point in my flailing.
List<string> emptycontrols = new List<string>();
foreach (Control control in Mainform.V_Datafield.Controls)
{
if (control.Text.Contains(null))
{
emptycontrols.Add(control.Name);
}
}
if (emptycontrols.Count > 0)
{
MessageBox.Show("Empty fields detected:", emptycontrols.ToString());
}
Above is my mediocre solution and when run it comes up that a control, namely the DateTimePicker control can never be empty and quite rightly so.
Ultimately my question is how would I exclude the DateTimePicker control from the foreach loop so that it will ignore it but continue to check the other controls?
The groupbox (V_datafield) contains:
10 x TextBoxes
1 x RichTextBox
1 x DateTimePicker as mentioned above.
You can always check like following inside your foreach loop
if (control is DateTimePicker)
continue;
You could use is like this:
foreach (Control control in Mainform.V_Datafield.Controls)
if (!(control is DateTimePicker) && string.IsNullOrEmpty(control.Text))
emptycontrols.Add(control.Name);
Or, actually, your loop could be removed using LINQ to become:
var emptyControls = Mainform.V_Datafield.Controls
.Cast<Control>()
.Where(control => !(control is DateTimePicker))
.Where(control => string.IsNullOrEmpty(control.Text))
.Select(control => control.Name);
using two Where to keep the logic from the previous code but they could be merged using &&.

How to retrieve data from dynamically created textboxes and build strings

So I have some code, that creates a row of 4 textboxes. The data from those 4 textboxes will be combined to make a SQL query and then executed. The button to add a row can be hit an infinite amount of times. I have my IDs generated so that on the first click textbox one is txtBox1Row1, then on the second click it is txtBox1Row2 etc, etc.
Now I need a way to retrieve the data from each row and build SQL queries from them. Just to reiterate, I only need the data from the 4 textboxes in each row per loop (I assume thats how this will need to be done).
So how do I go about doing this?
Thanks a lot, the help is always appreciated. I was planning on doing it like this:
foreach (Control c in pnlArea.Controls)
{
if (c.ID.Contains("ddlArea"))
{
area.Add(((DropDownList)c).SelectedValue);
}
if (c.ID.Contains("txtArea"))
{
areaOther.Add(((TextBox)c).Text);
}
if (c.ID.Contains("ddHazard"))
{
hazard.Add(((DropDownList)c).SelectedValue);
}
if (c.ID.Contains("txtHazard"))
{
hazardOther.Add(((TextBox)c).Text);
}
if (c.ID.Contains("txtHazardDesc"))
{
hazardDesc.Add(((TextBox)c).Text);
}
if (c.ID.Contains("txtActionDesc"))
{
actionDesc.Add(((TextBox)c).Text);
}
if (c.ID.Contains("calDueDate"))
{
dueDate.Add(((Calendar)c).SelectedDate);
}
}
Per Nkosi, you'd want to encapsulate your textbox 'area' in a form.
What I would recommend is looping through each textbox in the form and storing in a dictionary.
Here's what that might look like:
Dictionary<string, string> textBoxVals = new Dictionary<string, string>();
Control form = this.FindControl("form1") as Control;
TextBox tb;
foreach (Control c in form.Controls)
{
if (c.GetType() == typeof(TextBox))
{
tb = c as TextBox;
textBoxVals.Add(tb.ID, tb.Text);
}
}
Then you'd be able to loop through the dictionary to build your SQL string. The dictionary would contain both the dynamic name of the control and the value of the textbox.
Based on the code you posted it looks like maybe there are some other controls that might also be associated with each line. If that's the case, you can create another if statement in the foreach loop to handle different control types, so that you're saving the proper parameters of them.
I hope that helps.

Find a specific dynamic TextBox in a C# WPF GroupBox

I have added a GroupBox to my main Grid and am populating it dynamically with controls. I need to get a specific textbox within that GroupBox in an onClick event. I am able to loop through the GroupBox and fine, like this...
foreach (Control ctl in ((Grid)gpMccEngineProperties.Content).Children)
{
if (ctl.GetType() == typeof(TextBox))
{
TextBox textbox = (TextBox)ctl;
PropertyValue propertyValue = new PropertyValue();
propertyValue.Value = textbox.Text;
}
}
... but if i just want to access a specific TextBox i keep coming back with a null value. here is how i'm trying to get it...
TextBox txt = ((Grid)gpMccEngineProperties.Content).Children.OfType<TextBox>().Where(t => t.Name == "PropertyId_9") as TextBox;
... where PropertyId_9 is the name of a textbox that i added dynamically to the GroupBox. Any idea how i get that textbox so i can get it's value?
Thanks!
You're using the wrong Linq method. That code returns an IEnumerable of TextBoxes, not just the TextBox. Use Single or SingleOrDefault instead of Where:
TextBox txt = ((Grid)gpMccEngineProperties.Content).Children.OfType<TextBox>().Single(t => t.Name == "PropertyId_9");

Cannot Controls.Find a ComboBox inside a GroupBox

On my Visual C# Form application, I have a combobox inside a groupbox to help organize / look neat. However, once I put the combobox inside the groupbox, I am no longer able to find it by looping through all of the controls on my form.
For example, if I run this code with the Combobox inside the Groupbox I get a different result than if its outside the group box:
foreach (Control contrl in this.Controls)
{
richTextBox1.Text += "\n" + contrl.Name;
}
If the combobox is inside the groupbox, it won't find it.
I also noticed in the Form1.Designer.cs file that whenever I add the combobox inside the groupbox, the following line of code appears to the groupbox:
this.groupBox4.Controls.Add(this.myComboBox);
..
this.groupBox4.Location = new System.Drawing.Point(23, 39);
this.groupBox4.Name = "groupBox4";
... etc...
And this line will be removed:
this.Controls.Add(this.myComboBox);
If I try to edit it manually, it automatically switches back once I move the combobox back inside the groupbox.
Any help would be appreciated! Thanks!
Brian
As you said, you added combo box to group box, so it is added to Controls collection of group box and the designer generates this code:
this.groupBox4.Controls.Add(this.myComboBox);
So if you want to find the combo box programmatically, you can use this options:
Why not simply use: this.myComboBox ?
Use var combo = (ComboBox)this.Controls.Find("myComboBox", true).FirstOrDefault();
Use var combo = (ComboBox)this.groupBox4.Controls["myComboBox"]
Also if you want too loop, you should loop over this.groupBox4.Controls using:
foreach(Control c in this.groupBox4.Controls) {/*use c here */}
this.groupBox4.Controls.Cast<Control>().ToList().ForEach(c=>{/*use c here */})
Just like the Form object, the Group object can hold a collection of controls. You would need to iterate through the Group control's controls collection.
One more idea for getting at all or one ComboBox in a GroupBox, in this case groupBox1. Granted Resa's suggestion for using Find with FirstOrDefault would be best to access one combobox.
List<ComboBox> ComboBoxes = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control).ToList();
foreach (var c in ComboBoxes)
{
Console.WriteLine(c.Name);
}
string nameOfComboBox = "comboBox1";
ComboBox findThis = groupBox1
.Controls
.OfType<ComboBox>()
.Select((control) => control)
.Where(control => control.Name == nameOfComboBox)
.FirstOrDefault();
if (findThis != null)
{
Console.WriteLine(findThis.Text);
}
else
{
Console.WriteLine("Not found");
}
You can use the ControlCollections Find Method, it has a parameter that will search the parent and its Children for your control.
ComboBox temp;
Control[] myControls = Controls.Find("myComboBox", true); //note the method returns an array of matches
if (myControls.Length > 0) //Check that it returned a match
temp = (ComboBox)myControls[0]; //use it

Excluding the GroupBoxes that are inside another GroupBox

Let's say I have 7 group boxes but some of them also have group box inside them and some do not.
now if I want to iterate through those 7 group boxes and apply something to them, is there a way that I can exclude those Child group boxes from this loop?
though i question the choice of implementation (can you use polymorphism instead? what exactly are you trying to do?), there is a Parent property, e.g.
void soSomething(Control ctrl)
{
if (ctrl is GroupBox && (ctrl.Parent is null || !(ctrl.Parent is GroupBox)))
{
//do something here
}
foreach(Control child in ctrl.Controls)
{
doSomething(child);
}
}
Mark them with the tag property, or something.

Categories