Find which group box is enabled and which is not - c#

I have a form which contains more than 4 group boxes.Each group box has some text fields.What I am seeking is to get values from only that group box which is enabled. So my question is : Is it possible to scan all the available group boxes to find out if any of them is enabled and if one of them is enabled get and save values from only that group box into the database?

You can try using Linq; providing that GroupBoxes are placed directly on the form and TextBox of interest are directly on their GroupBoxes:
string[] values = Controls
.OfType<GroupBox>()
.Where(box => box.Enabled)
.SelectMany(box => box
.Controls
.OfType<TextBox>()
.Select(tb => tb.Text))
.ToArray();

You can scan the controls like this:
GroupBox gBox = this.Controls.OfType<GroupBox>().FirstOrDefault(c => c.Enabled);
List<string> values = new List<string>();
if(gBox != null)
{
foreach(var txtBox in gBox.Controls.OfType<TextBox>())
{
values.Add(txtBox.Text);
}
}
Note this assumes that the GroupBoxes are added directly to the form, and not to any panel. Also the TextBoxes are added directly to the GroupBox with no additional panels.
Alternatively, you can do it in one go:
List<string> result = this.Controls.OfType<GroupBox>()
.Where(gBox => gBox.Enabled)
.SelectMany(gBox => gBox.Controls.OfType<TextBox>())
.Select(txtBox => txtBox.Text).ToList();

Related

How to get all the TextBox names of a windows form when the name of each TextBox is changing

When I run my form, I just want to get the names of all the text boxes of the active form at run time in a label.
I searched a lot but all I found was something in which they haven't changed the names of text boxes.
var allTexboxes = this.Controls.OfType<TextBox>();
var sortedTextBoxes = allTexboxes
.Where(i => String.IsNullOrEmpty(i.Text))
.OrderBy(i => i.Name)
.ToArray();
Your code example and explanation of what you want is confusing. If you want an array of all textbox names within a form:
string[] GetTexBoxNames()
{
var names =new List<string>();
for each(var c in this.Controls)
{
if(c is TextBox)
{
names.Add(c.name);
}
}
return names.ToArray();
}
The phrase "this" is referring to the form. If you want to do this calculation from oitside the form, replace that keyword with a variable referencing it.
You can also use a lamda expression to get all textbox in an arrayin a single expression..
var textBoxNames = this.Controls
.Where(i => i is TextBox)
.ToArray();
Another thing you might want is a dictionary of all TextBoxes, with their names as the keys. You don't need this unless lookup speed is critical, because you can use a lamda to lookup a textbox in the final array which is slower than a dictionary lookup. You can use a simple for loop to go over every textbox and let them in a dictionary by name.
You probably can edit this code to suit your purpose if I got you wrong. Please clarify and I will update this answer as well.

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

Trying to figure out if any of the textboxes in a collection of textboxes have duplicate values (Visual C# 2010)

I'm automatically generating text boxes on a form based on a parameter in an Oracle Database. The user enters data in the format "A14/3". I've already got code putting all of the textboxes in a collection.
var sortedTextboxes = panel1.Controls
.OfType<TextBox>() // get all textboxes controls
.OrderBy(ctrl => ctrl.Text); // order by TabIndex
foreach (TextBox txt in sortedTextboxes)
{
//parse and check format
}
I need to figure out how to check for duplicates. I'm sorting by text, so all of the values will be in alphabetical order. Can I just check the current textbox's value with the previous textbox's value? If so, how can I do that?
You can get duplicate textboxes and their content if you group your results based on Text and then get only those items whose count is greater than 1. Like:
var sortedTextboxes = panel1.Controls
.OfType<TextBox>() // get all textboxes controls
.GroupBy(r => r.Text)
.Where(grp=> grp.Count() > 1)
.Select(grp => new
{
DuplicateText = grp.Key,
DuplicateTextBoxes = grp.Select(r => r).ToList(),
});
You could insert all the values into a hashset of strings then compare your text box collection count against the hashset collection count. If the are the same, you have no duplicates
var hash = new HashSet<string>();
foreach(var textBox in textBoxes){
if(hash.contains(textBox.Value){
break;
hash.add(textBox.Vaule);
}
if(hash.Count != textBoxes.Count){
//duplicate
}
Change your code to save previous text box id
var sortedTextboxes = panel1.Controls
.OfType<TextBox>() // get all textboxes controls
.OrderBy(ctrl => ctrl.Text); // order by TabIndex
var preTextboxId="";
foreach (TextBox txt in sortedTextboxes)
{
//parse and check format
if ( preTextboxId == txt.id)
{
//duplicate
}
else
{
add text box
}
preTextboxId = txt.id
}

How to retrieve a control with a certain property from a collection of Controls?

I create a menu application in an ASP.NET app like this:
// HTML
<td runat="server" id="container">
// C#. This logic is creating
// within a LOOP
Label l = new Label("name_blabla");
Panel p = new Panel();
p.Add(l);
container.Controls.Add(p);
At a given moment I assing the CSS class myclass to the label l:
l.CssClass="myClass";
So the container has only one panel containing only one label with this myclass name assigned.
The purpose is to get this panel from the container once all controls are inserted. I don't know the position where it is inserted. Better with LINQ.
You can use OfType<>() to filter panels, then apply SelectMany() to project the labels inside your panels, then Where() to check the CSS classes of the labels:
Label theLabel
= container.Controls.OfType<Panel>()
.SelectMany(panel => panel.Controls.OfType<Label>())
.Where(label => label.CssClass == "MyClass")
.FirstOrDefault();
EDIT: If you want to match the panel instead of the label, you can use Any():
Panel thePanel
= container.Controls.OfType<Panel>()
.Where(panel => panel.Controls.OfType<Label>().Any(
label => label.CssClass == "MyClass"))
.FirstOrDefault();

Selected Checkbox from a bunch of checkboxes in .c#.net

The problem is faced under c# .NET, Visual Studio, Windows Form Application
I have a bunch of checkboxes placed randomly in one form and in one panel.
So, If any checkbox is selected in the form its value is supposed to be added up.
Bottomline: Instead of using plenty of "If-else loops", to evaluate whether its been checked or not. I wanna simplify it using a "for loop ".
Is there any Checkbox group name type feature, which I can use???
I wanna code something like this:
for(int i=0;i<checkboxes.length;i++)
{
string str;
if(chkbox.checked)
{
str+=chkbox.value;
}
}
Where checkboxes is a group name.
You can use a simple LINQ query
var checked_boxes = yourControl.Controls.OfType<CheckBox>().Where(c => c.Checked);
where yourControl is the control containing your checkboxes.
checked_boxes is now an object which implements IEnumerable<CheckBox> that represents the query. Usually you want to iterate over this query with an foreach loop:
foreach(CheckBox cbx in checked_boxes)
{
}
You also can convert this query to a list (List<Checkbox>) by calling .ToList(), either on checked_boxes or directly after the Where(...).
Since you want to concatenate the Text of the checkboxes to a single string, you could use String.Join.
var checked_texts = yourControl.Controls.OfType<CheckBox>()
.Where(c => c.Checked)
.OrderBy(c => c.Text)
.Select(c => c.Text);
var allCheckedAsString = String.Join("", checked_texts);
I also added an OrderBy clause to ensure the checkboxes are sorted by their Text.
CheckBox[] box = new CheckBox[4];
box[0] = checkBox1;
box[1] = checkBox2;
box[2] = checkBox3;
box[3] = checkBox4;
for(int i=0; i<box.length; i++)
{
string str;
if(box[i].checked== true)
{
str += i.value;
}
}
I think this code will work with DotNet4.0. Plz let me know any error occurs. Treat 'box' as regular array.
If all the checkboxes are in a groupbox you can do this:
foreach(Control c in myGroupBox.Controls)
{
if (c is CheckBox)
{
//do something
CheckBox temp = (CheckBox)c;
if(temp.Checked)
//its checked
}
}
Subscribe all checkboxes to one CheckedChanged event handler and build your string when any checkbox checked or unchecked. Following query will build string, containing names of all Form's checked checkboxes:
private void Checkbox_CheckedChanged(object sender, EventArgs e)
{
// this will use all checkboxes on Form
string str = Controls.OfType<CheckBox>()
.Where(ch => ch.Checked)
.Aggregate(new StringBuilder(),
(sb, ch) => sb.Append(ch.Name),
sb => sb.ToString());
// use string
}
I suppose other than subscribing to event CheckedChanged there is no alternative even if it is contained in some panel or form, You have to use if else,
if it would have been web base eg asp.net or php we could use jquery because it gives us the option to loop through each particular event using .each and getting its value

Categories