Remove a checkbox that is being created dynamically in a loop - c#

I have a bunch of code that dynamicly creates some controls. It looks in a folder and lists the filenames in it. For each file in the folder it creates a checklistbox item, listbox item and two checkboxes. This is working great and as intended:
private void getAllFiles(string type)
{
try
{
string listPath = "not_defined";
if (type == "internal_mod")
{
int first_line = 76;
int next_line = 0;
int i = 0;
CheckBox[] chkMod = new CheckBox[100];
CheckBox[] chkTool = new CheckBox[100];
listPath = this.internalModsPath.Text;
string[] filesToList = System.IO.Directory.GetFiles(listPath);
foreach (string file in filesToList)
{
if (!internalModsChkList.Items.Contains(file))
{
internalModsChkList.Items.Add(file, false);
string fileName = Path.GetFileName(file);
internalModNameList.Items.Add(fileName);
//-----------------
// Draw Checkboxes
//-----------------
chkMod[i] = new CheckBox(); chkTool[i] = new CheckBox();
chkMod[i].Name = "modChk" + i.ToString(); chkTool[i].Name = "modChk" + i.ToString();
//chkMod[i].TabIndex = i; //chkTool[i].TabIndex = i;
chkMod[i].Anchor = (AnchorStyles.Left | AnchorStyles.Top); chkTool[i].Anchor = (AnchorStyles.Left | AnchorStyles.Top);
chkMod[i].Checked = true; chkTool[i].Checked = false;
chkMod[i].AutoCheck = true; chkTool[i].AutoCheck = true;
chkMod[i].Bounds = new Rectangle(549, first_line + next_line, 15, 15); chkTool[i].Bounds = new Rectangle(606, first_line + next_line, 15, 15);
groupBox7.Controls.Add(chkMod[i]); groupBox7.Controls.Add(chkTool[i]);
//-----------------
next_line += 15;
i++;
}
}
}
Now my problem is that I also want the user to be able to delete all these thing again based on the checklistbox' checked items.. I have no problems deleting the items in the checklistbox or the items in the listbox, but I want to remove the two checkboxes I create too ..
This is what I got to remove the items in the checklistbox, and the listbox
private void internalModListDel_btn_Click(object sender, EventArgs e)
{
int count = internalModsChkList.Items.Count;
for (int index = count; index > 0; index--)
{
if (internalModsChkList.CheckedItems.Contains(internalModsChkList.Items[index - 1]))
{
internalModsChkList.Items.RemoveAt(index - 1);
internalModNameList.Items.RemoveAt(index - 1);
groupBox7.Controls.Remove(modChk[index - 1]);
}
}
}
As you can see I have also tried to write something to remove the checkbox but it doesn't work and I have no idea how to make it work
Can you assist ?

Try using UserControls.
Use the ListBox controller to show those UserControls,
The user control can be built with those checkboxes, and the labels you want .
Another suggestion is to bind this list to an ObservableCollection which will contain the UserContorols you have created.
This way, it will be much more simlpe to add/remove/change the items inside.

Related

C# Dynamicaaly Add and Delete buttons

From the below code, I dynamically create a list of buttons based on client names provided by a TCP connection from the clientNames[i] list.
private void updateClientListUI()
{
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(this.updateClientListUI));
}
else
{
//Debug.WriteLine(clientNames[0]);
int basex = subPanelClient.Location.X;
int basey = subPanelClient.Location.Y;
for (int i = 0; i < clientNames.Count; i++)
{
Button b = new Button();
b.Left = basex;
b.Top = basey;
b.Size = new Size(25, 25); // <== add this line
b.Dock = DockStyle.Top;
b.ForeColor= Color.Gainsboro;
b.FlatStyle= FlatStyle.Flat;
b.FlatAppearance.BorderSize = 0;
b.Padding= new Padding(35, 0, 0, 0);
b.TextAlign = ContentAlignment.MiddleLeft;
basey += 25;
b.Name = clientNames[i];
b.Text = clientNames[i];
subPanelClient.Controls.Add(b);
buttonsAdded.Insert(i, b);
}
}
}
What I am trying to figure out, is how to delete a button (i). What I attempted is the following:
private void removingButtons(int i)
{
if (buttonsAdded.Count > 0)
{
Button buttonToRemove = buttonsAdded[i];
subPanelClient.Controls.Remove(buttonToRemove);
buttonsAdded.Remove(buttonToRemove);
}
}
Or if anyone would know how to update the current list of buttons from updateClientListUI() to the current latest list from clientNames[i] instead of a list being added onto another list.
The issue that Im getting is that obviously every time there is a connection or disconnection the list just keeps getting added instead of refreshing to the current list.
One way to do it would be to clear the old buttons on each update.
foreach (Button b in buttonsAdded)
{
subPanelClient.Controls.Add(b);
}
buttonsAdded.Clear();
for (int i = 0; i < clientNames.Count; i++)
{
Button b = new Button();
...
...
If the subPanelClient only contains those buttons, you could just use
subPanelClient.Controls.Clear();
Last remark: Your removingButtonk function seems to use this.Controls.Remove instead of subPanelClient.Controls.Remove.

Deleting dynamically created textbox

Good Day Everyone.
I'm creating function in which i dynamically generate textbox depending on the selected value in the dropdown list.
Here's the code.
comboboxNameHolder = ((ComboBox)sender).Name;
string comboboxNoHolder =comboboxNameHolder.Replace("cbFunctionList", "");
comboboxNo = Int32.Parse(comboboxNoHolder);
funcSelected = ((ComboBox)sender).SelectedItem.ToString();
for (int i = 0; i < optionList1.GetLength(0); i++)
{
if (funcSelected == optionList1[i, 0])
{
funcNoOfFields = optionList1[i, 1];
}
}
if (lineFieldController[comboboxNo, 1] == 0)
{
fieldCounter = Int32.Parse(funcNoOfFields);
lineFieldController[comboboxNo, 1] = fieldCounter;
inputField1 = new TextBox[fieldCounter];
for (int i = 0; i < fieldCounter; i++)
{
btnAddField0.Visible = false;
inputField = new TextBox();
inputField.Font = new Font("Microsoft Sans Serif", 11.25f);
inputField.Size = new Size(75, 24);
inputField.Location = new Point(positionController[comboboxNo, 0], positionController[comboboxNo, 1]);
inputField.Name = "txtLine" + comboboxNo.ToString() + "Variable" + i.ToString();
this.Controls.Add(inputField1[i]);
positionController[comboboxNo, 0] += 81;
}
}
Now I want in the same function when the lineFieldController is not equal to zero means that there are already created textbox in that line. When the user chooses another value in the dropdown list the number of fields will change by deleting the existing fields then creating new ones depending on the selected item.
How do I delete the textboxes I created?? I tried calling it by name but it doesn't work.
else
{
for(int i = 0; i < lineFieldController[comboboxNo, 1]; i++)
{
string name = "txtLine" + comboboxNo.ToString() + "Variable" + i.ToString();
TextBox tb = this.Controls.Find(name, true);
}
}
Hoping for your kind response
you can put all controls that you have created put them to the list and hold reference on controls were created at runtime.
like
public class Form1
{
List<Control> createdList = new List<Control>(); // class field
void combobox_SelectedIndexChanged()
{
// removing controls were created before
foreach (var created in createdList)
{
this.Controls.Remove(created);
created.Dispose();
}
createdList.Clear(); // all created controls from previous index changed should be removed here
// add each control you are creating to the createList additionally
inputField1 = new TextBox[fieldCounter];
for (int i = 0; i < fieldCounter; i++)
{
btnAddField0.Visible = false;
inputField = new TextBox();
createdList.Add(inputField); //store reference
/// skipping init code
this.Controls.Add(inputField1[i]);
positionController[comboboxNo, 0] += 81;
}
}
}
another option is to add panel on the form as a placeholder for all controls are being created. You have to change this.Controls.Add(inputField1[i]); to the panelCreated.Controls.Add(inputField1[i]);
Then you can grab all controls from the panel and remove them without name search like below
foreach (Control created in panelCreated.Controls)
created.Dispose();
panelCreated.Controls.Clear();

Populate TextBoxes from a List

I am trying to populate TextBoxes from a list. I have been able to populate ComboBoxes with comboList:
var comboList = new System.Windows.Forms.ComboBox[4];
comboList[0] = cmbSite1Asset;
comboList[1] = cmbSite2Asset;
comboList[2] = cmbSite3Asset;
comboList[3] = cmbSite4Asset;
List<CRCS.CAsset> assets = _rcs.Assets;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int i = 0; i < 4; ++i)
{
comboList[i].Items.Add(id);
}
}
But when I try and apply the same principle to TextBoxes
var aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
foreach (CRCS.CAsset asset in assets)
{
string id = asset.ID;
for (int n = 0; n < 8; ++n)
{
aosList[n].Items.Add(id);
}
}
TextBox does not like Items.Add ( aosList[n]Items.Add(id); )
I am looking fore a reference or guidance resolving this issue. Thanks!
You should use ComboBox for your problem,instead of iterating on each element,You simply use below lines to populate combobox.
comboList.DataSource=assets;
comboList.DisplayMember="ID";
comboList.ValueMember="ID";
However,if you want your values in TextBox,you can use TextBox.AppendText Method, but it will not work like ComboBox as it will contain texts+texts+texts, will not have indexes like ComboBox.
private void AppendTextBoxLine(string myStr)
{
if (textBox1.Text.Length > 0)
{
textBox1.AppendText(Environment.NewLine);
}
textBox1.AppendText(myStr);
}
private void TestMethod()
{
for (int i = 0; i < 2; i++)
{
AppendTextBoxLine("Some text");
}
}
A Combobox is a collection of items, and so has an Items property from which you can add/remove to change it's contents. A Textbox is just a control that displays some text value, so it has a Text property which you can set/get, and which denotes the string that is displayed.
System.Windows.Forms.TextBox[] aosList = new System.Windows.Forms.TextBox[8];
aosList[0] = txtAsset1;
aosList[1] = txtAsset2;
aosList[2] = txtAsset3;
aosList[3] = txtAsset4;
aosList[4] = txtAsset5;
aosList[5] = txtAsset6;
aosList[6] = txtAsset7;
aosList[7] = txtAsset8;
for (int n = 0; n < 8; ++n)
{
aosList[n].Text = assets[n].ID; // make sure you have 8 assets also!
}
int i = 1;
foreach (var asset in assets)
{
this.Controls["txtAsset" + i].Text = asset.ID;
i++;
}

How can I use text property of dynamic created textfield?

I have this code, which dynamically creates some textfields for me. k is taken from user btw.
for (int i = 0; i < k; i++)
{
TextBox t1 = new TextBox();
t1.Parent = groupBox2;
t1.Left = textBox2.Left;
t1.Top = textBox2.Top + (i + 1) * 40;
t1.Name = "text" + (i + 1);
t1.Enabled = true;
groupBox2.Controls.Add(t1);
}
What i want to do is, after this creating phase is done, when the user presses groupbox2's "OK" button, I want to take the created textfields' text properties, but so far I don't know how could this be done, since I gave textfields a name, I tried this but didn't work.
private void button3_Click(object sender, EventArgs e)
{
node1.name = textBox2.Text;
for (int i = 0; i < k; i++)
{
node1.array[i] = Convert.ToInt32("text"+(i+1).Text);
}
}
Any help would be nice, thanks.
Try this method:
private void button3_Click(object sender, EventArgs e)
{
node1.name = textBox2.Text;
for (int i = 0; i < k; i++)
{
TextBox txtBox = (TextBox)groupBox2.FindControl("text" + (i + 1));
if (txtBox != null)
{
node1.array[i] = txtBox.Text;
}
}
}
Loop through your text boxes in groupBox1 and get their names,Try this:
List<string> TextBoxesName=new List<string>();
foreach (Control item in groupBox1.Controls)
{
if (item is TextBox)
{
TextBoxesName.Add((item as TextBox).Text);
}
}
Set to your dynamic texboxes ID and than you can do groupBox2.FindControl("dynamic_texbox_id") to get your text box
Easiest solution is to put your listboxes in a collection of some sort
List<ListBox> listboxes = new List<ListBox>();
for (...)
{
...
listboxes.add(listbox);
}
Then you can refer back to them whenever you want
Or since you're adding them to a groupbox, why not go through that collection?

Problem with updating ListBox control in WPF

I have an application which has to monitor 211 rods, and every 5 seconds it will update 2 ListBox controls, each one containing either the inserted rods or the removed ones. When I manually use the button for inserting/removing rods the code executes perfectly and the ListBoxes update properly. When I use the global button which inserts all 211 one of the ListBox controls stops working properly.
The code for ListBox update
bool IClear = true, RClear = true;
for (int foo = 0; foo < Rods.Count; foo++)
{
if (Rods[foo].State == RodState.Inserted)
{
UpdateRodList update = new UpdateRodList(UpdateIRodUI);
if (IClear)
{
InsertedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, true);
IClear = false;
}
else
{
InsertedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, false);
}
}
if (Rods[foo].State == RodState.Removed)
{
UpdateRodList update = new UpdateRodList(UpdateRRodUI);
if (RClear)
{
RemovedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, true);
RClear = false;
}
else
{
RemovedRods.Dispatcher.BeginInvoke(update, System.Windows.Threading.DispatcherPriority.Normal, foo, false);
}
}
}
The code for the insert button (the remove one is similar)
Int32[] RodsID = null;
bool bParsed = false;
if (RemovingRods_.Text.Contains("*"))
{
RodsID = new Int32[211];
for (int i = 0; i < 211; i++)
{
RodsID[i] = i;
}
RemovingRods_.Text = "";
bParsed = true;
}
if (RemovingRods_.Text.Contains("-"))
{
string stext = RemovingRods_.Text;
Int32 a = Int32.Parse(RemovingRods_.Text.Substring(0, RemovingRods_.Text.IndexOf("-")));
Int32 b = Int32.Parse(RemovingRods_.Text.Substring(RemovingRods_.Text.IndexOf("-") + 1));
RodsID = new Int32[b - a];
for (int i = 0; i < b - a; i++)
{
RodsID[i] = i + a;
}
RemovingRods_.Text = "";
bParsed = true;
}
if (!bParsed)
{
string[] RodsID_;
char[] split = { ' ' };
RodsID_ = RemovingRods_.Text.Split(split);
RemovingRods_.Text = "";
RodsID = new Int32[RodsID_.Length];
for (int i = 0; i < RodsID_.Length; i++)
{
RodsID[i] = Int32.Parse(RodsID_[i]);
}
}
foreach (int numb in RodsID)
{
if (Rods[numb].Type == "Control Rod")
{
ControlRod Rod = new ControlRod();
Rod.Number = numb;
Rod.RodState = RodState.Changing;
RemovingCRods.Add(Rod);
}
if (Rods[numb].Type == "Shortened Control Rod")
{
ShortenedControlRod Rod = new ShortenedControlRod();
Rod.Number = numb;
Rod.RodState = RodState.Changing;
RemovingSRods.Add(Rod);
}
if (Rods[numb].Type == "Automated Control Rod")
{
// Automated Rods -- NO MANUAL CONTROL
}
}
And the global button code
try
{
Int32[] RodsID = null;
string text = "0-211";
RodsID = new Int32[211];
for (int i = 0; i < 211; i++)
{
RodsID[i] = i;
}
foreach (int numb in RodsID)
{
if (Rods[numb].Type == "Control Rod")
{
ControlRod Rod = new ControlRod();
Rod.Number = numb;
Rod.RodState = RodState.Changing;
InsertingCRods.Add(Rod);
}
if (Rods[numb].Type == "Shortened Control Rod")
{
ShortenedControlRod Rod = new ShortenedControlRod();
Rod.Number = numb;
Rod.RodState = RodState.Changing;
InsertingSRods.Add(Rod);
}
if (Rods[numb].Type == "Automated Control Rod")
{
AutomatedControlRod Rod = new AutomatedControlRod();
Rod.Number = numb;
Rod.RodState = RodState.Changing;
InsertingARods.Add(Rod);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
What happens is when I press the global one, the Removed Rods ListBox will have all the rods as it should, and the Inserted Rods ListBox will contain the rods that were inserted before I pressed the button. It's as if when I pressed this button, this control doesn't update. P.S. If I remove rods manually using the button or insert it works perfectly.
As for the code requested by Marko:
private void UpdateIRodUI(Int32 foo, Boolean clear)
{
if (clear)
{
InsertedRods.Items.Clear();
}
InsertedRods.Items.Add(Rods[foo].Number + " : " + Rods[foo].Type + " (" + foo.ToString() + ")");
}
private void UpdateRRodUI(Int32 foo, Boolean clear)
{
if (clear)
{
RemovedRods.Items.Clear();
}
RemovedRods.Items.Add(Rods[foo].Number + " : " + Rods[foo].Type + " (" + foo.ToString() + ")");
}
Update: I have put the update ListBox code in a seperate function and took Marko's advice and also put in a function the InsertRods. Everything works fine now, but it seems that after I press the "emergency" button the InsertedRods ListBox updates and works just fine but RemovedRods just stops updating, unless I do it manually (it's supposed to update every 5 seconds through a Tick event). I even tried inserting all the rods, updating the ListBoxes and the clearing the "faulty" ListBox and still nothing, same result.
I just took a quick glance of your posted code without focusing very deeply on it and a couple of questions popped into mind:
1) You posted your code for ListBox update, but it's unclear from the other two code pieces that where do you call the ListBox update method?
2) The code that you posted for "insert button" looks more like the code from the "remove button", because of Removing_Rods.Add()... But why do you duplicate your insert/remove button code in your global button code? Why not have an insert method, that both the insert button and global (insert) button call? And the same for remove. If you need to slightly alter the code based on whether the caller is the insert button or the global button, you can pass in a variable and check it inside the insert method.
3) Have you tried debugging your code? As in whether the listbox update method is called when the global button code is executed...

Categories

Resources