How to access dynamically created controls in C#? - c#

I have dynamically created checkbox's. I have an option "Select All". How do I select all the dynamically created checkboxes in C#?
How to select all the dynamic checkboxes which have been created?
protected void chkbox_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkBtn = new CheckBox();
chkBtn = sender as CheckBox;
selectedTypeId.Add(Convert.ToInt16(chkBtn.Name));
foreach(int id in selectedTypeId)
{
Console.WriteLine(id);
}
}

Declare a global List of CheckBoxes:
List<CheckBox> boxes;
And on your program start instantiate it.
boxes = new List<CheckBox>();
Each time you dynamically add a CheckBox, also add it to your List.
CheckBox chkBtn = new CheckBox();
boxes.Add(chkBtn);
When you want to check them all at once, use a loop to go through the list.
foreach(CheckBox box in boxes)
box.Checked = true;

You can get all of the CheckBoxes of the control like so:
var checkBoxes = this.Controls.OfType<CheckBox>();
checkBoxes.ToList()?.ForEach(x=>x.Checked = true);
But typically you would put all of the checkboxes in groupbox (from ux perspective)
groupBox.Controls.Add(checkBox);
and then get them from the groupbox:
var checkBoxes = groupBox.Controls.OfType<CheckBox>();

Related

Set multiple TextBoxes editable after button click on WinForm

I have set all my TextBoxs.readOnly = true; in the form by default.
But when an Edit Button is clicked.
I want it to make all the TextBoxs.readOnly = false;
I have tried;
private void btnEdit_Click(object sender, EventArgs e)
{
foreach (var textBox in this.Controls.OfType<TextBox>())
textBox.ReadOnly = false;
}
Each TextBox has a unique name.
The easiest way to do it would be this, below. But I don't want to do it that way.
txtName.ReadOnly = false;
txtAddress.ReadOnly = false;
...
With this approach you can set just TextBoxes's ReadOnly that are placed directly in your form not those that are inside another container like GroupBox or Panel. You need a recursive method for this purpose if you have more than one container (example1, example2). But Since all your TextBoxes are inside one GroupBox then simply replace this with your GroupBox's Name like this:
foreach (var textBox in groupBox1.Controls.OfType<TextBox>())
textBox.ReadOnly = false;

Controlling Dynamic Checkbox in C#

My task is to read entries from a database and put a Checkbox corresponding to each entry
I have opened a database connection and have created the checkboxes but am unable to check the setting of the checkbox. I am storing my checkboxes using a static array ck[]
int count = 0;
while(dr.Read()) //Reading the Database
{
CheckBox temp = new CheckBox(); //Creating a temprory checkbox
temp.Text = dr[1].ToString();
temp.Checked = false; //Making the checkbox intitally empty
temp.ID = dr[0].ToString();
ck[count] = temp; //inserting the checkbox's references into the array
ck[count].CheckedChanged += new EventHandler(temp_CheckedChanged); //Adding the even handler
Panel1.Controls.Add(ck[count]); //Adding the checkbox to panel
LiteralControl lc = new LiteralControl("<br>");
Panel1.Controls.Add(lc);
count++;
}
void temp_CheckedChanged(object sender, EventArgs e) //handling the checking and unchecking of the checkbox
{
CheckBox ckb = (CheckBox)sender;
ck[index].Checked = !ck[index].Checked;
}
The problem arises in the fact that there is no update in the .Checked entry of the checkboxes.
I have read many posts here and tried to implement them too but nothing has worked out so far. I have even tried reading the data from the pane on which I am showing it in.
Better to use checkboxlist. Because you can add items at run time and works like list.

Checking if the Checkbox is checked or not dynamically in c#

I have created a Checkbox dynamically by this button code
private void btn_add_record_Click(object sender, EventArgs e)q2
{
CheckBox DeleteCheckBox = new CheckBox();
Point P_request = new Point(nXCheckBox, nYCheckBox);
DeleteCheckBox.Location = P_request;
DeleteCheckBox.Name = "CH"+Record_ID+"";
}
Then i Checked it manually
Then i need to check a specific checkbox its name is "CH"+Record_ID+" to be checked or not dynamically using this code
string ChechBoxName = "CH1";
CheckBox DeleteChechBox = new CheckBox();
DeleteChechBox.Name = ChechBoxName;
if (DeleteChechBox.Checked)
{
// To Do Code
}
When i debug this code, it doesn't enter the if statement .. WHY ?
You're checking if the box is checked before it gets checked. Add
DeleteChechBox.CheckedChanged += DeleteChechBoxCheckedChanged;
and add the method DeleteChechBoxCheckedChanged where you can test whether or not it's been checked. You can also use
DeleteChechBox.Checked = true;
to check the box through code.
Edit:
To get a certain checkbox by it's name you have to either store it as a global variable or look through the controls array in the form.
foreach (Control control in this.Controls)
{
if (control.Name == "CH1")
{
CheckBox DeleteChechBox = (CheckBox)control;
if (DeleteChechBox.Check)
{
//To Do Code
}
}
}
When you create a new CheckBox, the default Checked value is false. Therefore if (DeleteChechBox.Checked)
returns false which is why you don't enter the block. You're not checking any existing Checkboxes, you're checking the new one you created.
In WPF you can accomplish it like shown in the following code snippet (pertinent to your example):
string _strCheckBoxName = "CH1";
CheckBox DeleteCheckBox= new CheckBox();
DeleteCheckBox.Name = _strCheckBoxName ;
DeleteCheckBox.Checked+=(s,e)=>CheckBox_Change(s,e);
DeleteCheckBox.Unchecked+=(s,e)=>CheckBox_Change(s,e);
DeleteCheckBox.IsChecked = true;
private void CheckBox_Change(object sender, RoutedEventArgs e)
{
if ((sender as CheckBox).Name=_strCheckBoxName && (bool)(sender as CheckBox).IsChecked)
{
// To Do Code
}
}
In suggested solution, you essentially subscribe the newly created CheckBox control to a single event handler proc, which looks at the control name and if checked runs some code. If more CheckBox added, then use the same event-subscription technique pointed to the same handler, and extend it with another if statement (or if-else if, or switch statement).
Hope this will help. Rgds,
Your problem is that you are creating one CheckBox in your btn_add_record_Click handler and then creating a new one in your second code fragment, which just happens to have the same Name as the first. That notwithstanding, it is not the same check box, so will not have the same value for its Checked property.
The way to fix that is to create the checkbox in the form's constructor as a class member, and then discover it when you need it by searching the components, using the code which Xylorast showed:
foreach (Control control in this.Controls)
{
if (control.Name == "CH1")
{
CheckBox DeleteChechBox = (CheckBox)control;
if (DeleteChechBox.Check)
{
//To Do Code
}
}
}
This is what I meant. Maybe you already checked it..?
string ChechBoxName = "CH1";
CheckBox DeleteChechBox = new CheckBox();
DeleteChechBox.Name = ChechBoxName;
DeleteChechBox.Checked = true;
if (DeleteChechBox.Checked)
{
// To Do Code
}
Edit:
Here is another way of accessing the control instead of enumerating over all the controls on the form for each control you would like to access:
Dictionary<string, CheckBox> checkBoxCollection = new Dictionary<string, CheckBox>();
And in your method where you create the checkbox add it to the dictionary:
checkBoxCollection.Add("CH1",DeleteCheckBox);
Access the checkbox from wherever you want like this:
CheckBox checkBox;
bool success = controls.TryGetValue("CH1"), out checkBox);
if (success)
{
// To Do Code
}
Or in your CheckedEvent you can get the CheckBox being checked like this:
CheckBox checkBox = sender as CheckBox;

Dynamically creating checkboxes from an array and then iterate through them to check for selected

I have been creating a list of checkboxes from returned information from a webservice. The checkboxes render as expected but when I try and then read them to check if they have been selected the code cannot find them.
I have created a panel called planList and had the code loop creating the dynamic list of boxes - then on a button being pressed it should iterate through the list of checkboxes to see if the user has selected any values. The code doesn't seem to be picking up any checkboxes unless created dynamically. Anyone able to assist? At the moment I am just trying to pull out the ID if it picks up a checkbox
Code:
planList.Controls.Add(new LiteralControl("<h2>Plan List </h2>"));
foreach (string[] ar in ws.planS(this.txtGetDetails.Text)) {
CheckBox cb = new CheckBox();
cb.Text = ar[1].ToString();
cb.ID = ar[0];
planList.Controls.Add(cb);
planList.Controls.Add(new LiteralControl("<b> Application ID: " + ar[2] + "</b>"));
planList.Controls.Add(new LiteralControl("<br>"));
}
protected void Uploadbutton_Click1(object sender, System.EventArgs e) {
foreach (Control c in planList.Controls) {
CheckBox chx = c as CheckBox;
if (chx != null) {
var planid = c.ID;
}
}
}
You have to override the CreateChildControls method and add the checkboxes there. With this, you are creating the controls tree before loading the ViewState, which contains the data of which one was checked.

how to dynamically add combobox in windows forms(C#) and bound it to a column of a table in sql database

My windows form has an ADD button which adds a combo box to the form after each click. The problem is, i am not able to bind it to a table column at run time. Using an existing databinding source selects the same value in all the combo boxes. I am coding in C#
here is the sample code :
ComboBox ocbNext = new ComboBox();
//HAVE set the rest of the properties right, the problem is with the databinding
ocbNext.DataSource = this.dummysubjectBindingSource;
ocbNext.DisplayMember = "sub_name";
ocbNext.ValueMember = "sub_name";
this.Controls.Add(ocbNext);
I added a DataSet to the solution and droped the Employees table (from Northwind) in the designer, which automatically created the employeesBindingSource. I dropped a combobox and a button on the Form and I set the DataSource and DataMember of the combo. Then I handled some events:
private void Form1_Load(object sender, EventArgs e)
{
this.employeesTableAdapter.Fill(this.dS.Employees);
}
private int _i = 0;
private void button1_Click(object sender, EventArgs e)
{
ComboBox combo = new ComboBox();
combo.DataSource = this.employeesBindingSource;
combo.DisplayMember = this.dS.Tables[0].Columns[++_i].ColumnName;
combo.Location = new Point(comboBox1.Location.X, comboBox1.Location.Y + comboBox1.Height * _i);
this.Controls.Add(combo);
}
So on each click, a new combo is added onto the form dynamically right under the previous combo. The combo is also bound to the next column in the Employees table (no boundary checks however).
As you can see, this is pretty easy stuff. Hope this helps.
Okay, so here is a variation of the code that could help you with that other question you asked in the comments of this answer.
It assumes you have a Form with a button and a DataSet with table Employees. On button click it creates a combo, and fills it with data (the Name column of Employees). Each time you add a combo, it gets its own copy of the data (this is important to be able to remove items from one combo at a time). Then, every time you select a value in the combo, the combo is disabled and the other combos don't have that selected value in their list.
private int _i = 0;
private void button1_Click(object sender, EventArgs e)
{
DataSet dataS = dS.Clone();
this.employeesTableAdapter.Fill((DS.EmployeesDataTable)dataS.Tables[0]);
BindingSource bindSource = new BindingSource(dataS, "Employees");
ComboBox combo = new ComboBox();
combo.Name = this.dS.Tables[0].Columns[0].ColumnName + (++_i).ToString();
combo.DataSource = bindSource;
combo.DisplayMember = this.dS.Tables[0].Columns[1].ColumnName; //This column is the Name of Employee
combo.Location = new Point(button1.Location.X, button1.Location.Y + combo.Height * _i);
combo.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);
this.Controls.Add(combo);
}
private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
foreach (Control ctrl in this.Controls)
{
if (ctrl is ComboBox && ctrl != sender && ctrl.Enabled)
{
((BindingSource)((ComboBox)ctrl).DataSource).RemoveAt(((ComboBox)sender).SelectedIndex);
}
}
((ComboBox)sender).Enabled = false;
}
This is pretty close to what you require, or easily adaptable to meet your expectations. Enjoy and please select an answer as the accepted one. Thanks!
Option 1: Fill the combobox with strings:
this.comboBox1.Items.Add("Syed");
this.comboBox1.Items.Add("Baqar");
Option 2: Fill the combobox with an array of strings:
this.comboBox1.Items.AddRange(new object[] { "Syed", "Baqar" });
You need to add controls to the parent window first, and then set the data source.
ComboBox ocbNext = new ComboBox();
this.Controls.Add(ocbNext);
ocbNext.DisplayMember = "sub_name";
ocbNext.ValueMember = "sub_name";
ocbNext.DataSource = this.dummysubjectBindingSource;
Should be fine if you create a new local ComboBox variable in the clickevent. If you use a global variable for the ComboBox this might explain your problems. But without a sample how you're doing it's hard to see what's really happening, so think this is just a rough guess

Categories