C# How to remove dynamically created controls in switch - c#

ok so in my switch(comboBox1.SelectedIndex) in case 1 it creates some Labels and comboBoxes dynamically and adds them to tabPage1, but I want those dynamically created controls to be removed when case 2 is selected
public void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox2.SelectedIndex)
{
case 0:
{
//do nothing.
break;
}
case 1:
{
Label label16 = new Label();
tabPage1.Controls.Add(label16);
label16.Left = 465;
label16.Top = 111;
label16.Text = "Time:";
label16.Size = new Size(60, 13);
ComboBox comboBox13 = new ComboBox();
tabPage1.Controls.Add(comboBox13);
comboBox13.Left = 533;
comboBox13.Top = 108;
comboBox13.Size = new Size(104, 21);
comboBox13.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox13.DisplayMember = "Text";
comboBox13.ValueMember = "Value";
var ComboBox13Items = new[] {
new { Text = "1 Second", Value = "1" },
new { Text = "2.5 Seconds", Value = "2.5" },
new { Text = "5 Seconds", Value = "5" },
new { Text = "7.5 Seconds", Value = "7.5" },
new { Text = "10 Seconds", Value = "10" }
};
comboBox13.DataSource = ComboBox13Items;
break;
}
case 2:
{
foreach (Control TimeLabel in tabPage1.Controls.OfType<Controls>())
{
if (TimeLabel.Name == "label16")
tabPage1.Controls.Remove(TimeLabel);
}
foreach (Control TimeComboBox in tabPage1.Controls.OfType<Controls>())
{
if (TimeComboBox.Name == "comboBox13")
tabPage1.Controls.Remove(TimeComboBox);
}
break;
}
I also tried changing OfType<Controls> to OfType<Label> and OfType<ComboBox>, still no luck :/

Label label16 = new Label();
tabPage1.Controls.Add(label16);
label16.Left = 465;
label16.Top = 111;
label16.Text = "Time:";
label16.Size = new Size(60, 13);
Does not create a button called "label16" it creates an unnamed button.
you would need to add
labal16.Name = "label16";
Names should be unique, keep a counter or something if theres chance that more than one set would be added and use the counter to make a unique name.

Related

Match the columns using a data dictionary in C# winForm

private void Dewery_Decimal_System_Load(object sender, EventArgs e)
{
Random random = new Random();
Dictionary<int,string > dictionary = new Dictionary<int, string>();
dictionary.Add(000, "Genral Knowlege");
dictionary.Add(100, "philosophy & Psycology");
dictionary.Add(200, "Religion");
dictionary.Add(300, "Social Sciences");
dictionary.Add(400, "Languages");
dictionary.Add(500, "Science");
dictionary.Add(600, "Techynology");
dictionary.Add(700, "Arts & Recriation");
dictionary.Add(800, "Litrature");
dictionary.Add(900, "History and geography");
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
Console.WriteLine("key: " + pair.Key + ", value: " + pair.Value);
label28.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label29.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label30.Text = (dictionary[pair.Key]);
}
for (int i = 0; i < 9; ++i)
{
int index = random.Next(dictionary.Count);
KeyValuePair<int, string> pair = dictionary.ElementAt(index);
label31.Text = (dictionary[pair.Key]);
}
}
private void button15_Click(object sender, EventArgs e)
{
}
**I would want my end result to be that the application displays 4 call numbers from the dictionary and lets the user select the corresponding description **
I've never worked with a data dictionary before so I'm sorry for the mess iv created but I'm trying to better my skills doing these challenges but this particular one is really giving me grief
Based on the questions and comments, your request is to allow a user selecting a value from a set of predefined key-value pairs within a dictionary.
I will assume that the component you are using on the windows form is a combobox.
Dictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(000, "Genral Knowlege");
dictionary.Add(100, "philosophy & Psycology");
dictionary.Add(200, "Religion");
dictionary.Add(300, "Social Sciences");
dictionary.Add(400, "Languages");
dictionary.Add(500, "Science");
dictionary.Add(600, "Techynology");
dictionary.Add(700, "Arts & Recriation");
dictionary.Add(800, "Litrature");
dictionary.Add(900, "History and geography");
//Repeat this step for all your comboboxes
foreach (KeyValuePair<int, string> item in dictionary)
{
comboBox1.Items.Add(item.Value);
comboBox1.ValueMember = item.Value.ToString();
comboBox1.DisplayMember = item.Key.ToString();
comboBox1.SelectedIndex = 0;
}
Now, each combobox is filled with the dictionary values, the user can either type or choose from the suggested value.
Ok here is the answer I promised without knowing the details in comment. This is a working and quick throw at it. You should really think about the purpose of what you are doing twice.
Note the repetition in code, it could be made not to repeat (in a loop) but I left that you for now and wanted to be more explicit:
void Main()
{
Dictionary<string, string> dictionary = new Dictionary<string, string>();
dictionary.Add("000", "Genral Knowlege");
dictionary.Add("100", "philosophy & Psycology");
dictionary.Add("200", "Religion");
dictionary.Add("300", "Social Sciences");
dictionary.Add("400", "Languages");
dictionary.Add("500", "Science");
dictionary.Add("600", "Techynology");
dictionary.Add("700", "Arts & Recriation");
dictionary.Add("800", "Litrature");
dictionary.Add("900", "History and geography");
Form f = new Form();
var label28 = new Label { Top = 10, Left = 10, Width = 100 };
var label29 = new Label { Top = 40, Left = 10, Width = 100 };
var label30 = new Label { Top = 70, Left = 10, Width = 100 };
var label31 = new Label { Top = 100, Left = 10, Width = 100 };
var cmb28 = new ComboBox { Top = 10, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb29 = new ComboBox { Top = 40, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb30 = new ComboBox { Top = 70, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
var cmb31 = new ComboBox { Top = 100, Left = 130, DataSource = dictionary.ToList(), DisplayMember = "Key", ValueMember = "Key" };
f.Controls.AddRange(new Control[] { label28, label29, label30, label31, cmb28, cmb29, cmb30, cmb31 });
f.Load += (sender, args) => {
var randomTop4 = dictionary.ToList().OrderBy(d => Guid.NewGuid()).Take(4).ToList();
cmb28.SelectedValue = randomTop4[0].Key;
label28.Text = randomTop4[0].Value;
cmb28.SelectedValueChanged += (s, a) => {
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label28.Text = dictionary[v];
}
};
cmb29.SelectedValue = randomTop4[1].Key;
label29.Text = randomTop4[1].Value;
cmb29.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label29.Text = dictionary[v];
}
};
cmb30.SelectedValue = randomTop4[2].Key;
label30.Text = randomTop4[2].Value;
cmb30.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label30.Text = dictionary[v];
}
};
cmb31.SelectedValue = randomTop4[3].Key;
label31.Text = randomTop4[3].Value;
cmb31.SelectedValueChanged += (s, a) =>
{
var v = (string)(s as ComboBox).SelectedValue;
if (v != null)
{
label31.Text = dictionary[v];
}
};
};
f.Show();
}

Where is data updated in a DataGridView?

I am creating a tab page entirley programatically from a button press in the root page of a tabbed control. At present all the page initialisation takes place in the button click method. After all the instantiation, data capture from file and so on, I finally want to adjust the column widths in the data grid view, so that all the row data appears without having to have horizontal scroll bars. With the help of all your contributors I have managed to get it all working but the last step. Running at full speed it appears the DataGridView is accessed before the data load from the table is complete as it fails with an exception because the count derived from RegistersGrid.ColumnCount (local variable l) is zero. It all works fine if I step through the code. I am assuming that I need to put a Mutex of some form to wait for the transfer to complete, but I can't work out where that is taking place in order to reset the flag! If someone can point me in the right direction or if there is better more structured way to approach this I would deeply appreciate the help :-)
I have included all the code in the method just in case, I am afraid I date back a long way so if this looks like the awkward child of assembler,pascal and c with a little c# thrown in, my apologies....it's my age :-)
private void AddModuleButton_Click(object sender, EventArgs e)
{
string ModuleID = null;
string ModuleTypeFileNumber = null;
string ModuleType = null;
int TabID = 0;
openFileDialog1.Filter = "Text Files (.txt)|*.txt";
DialogResult result = openFileDialog1.ShowDialog();
if (result == DialogResult.OK)
using (StreamReader reader = new StreamReader(openFileDialog1.FileName))
{
string newline;
if ((newline = reader.ReadLine()) != null)
{
string[] values = newline.Split((char)9);
ModuleTypeFileNumber = values[1];
}
if ((newline = reader.ReadLine()) != null)
{
string[] values = newline.Split();
ModuleID = values[0];
ModuleType = values[1];
}
bool AbsorbLines = true;
while (AbsorbLines && ((newline = reader.ReadLine()) != null))
{
string[] values = newline.Split();
if (values[0] == "Readings") AbsorbLines = false;
}
string[] columnnames = { "Summary", "access", "register", "Module & Name", "Value", "unit", "type", "Res" };
string[] columntypes = { "System.Boolean", "System.String", "System.Int32", "System.String", "System.Int32", "System.String", "System.String", "System.String" };
int[] columnwidth = { 1,2,3,35,10,5,5,5 };
DataTable dt = new DataTable();
for(int i =0; i < columnnames.Length; i++)
{
DataColumn colString = new DataColumn(columnnames[i]);
colString.DataType = System.Type.GetType(columntypes[i]);
dt.Columns.Add(colString);
}
while (ImportTable("Controls", reader.ReadLine(), dt, "RO")) { } // Import the "readings" section
while (ImportTable("Status bits", reader.ReadLine(), dt, "RW")) { } // Import the "controls" section
reader.Close();
registerTables.Add(ModuleID, dt);
// create a new tab page
TabPage page = new TabPage(ModuleID);
InterbusRegisters.TabPages.Add(page);
//
// tabPage1
//
Button ResizeButton = new Button();
Button RemoveButton = new Button();
Label VersionLabel = new Label();
Label SerialNolabel = new Label();
TextBox VersionNoTB = new TextBox();
TextBox SerialNoTB = new TextBox();
DataGridView RegistersGrid = new DataGridView();
//
// Set the properties of the DataGrid.
//
RegistersGrid.AccessibleName = ModuleID + "Grid";
RegistersGrid.Location = new System.Drawing.Point(3,29);
RegistersGrid.Width = page.Width - 6;
RegistersGrid.Height = page.Height - 29;
RegistersGrid.Anchor = (AnchorStyles.Top | AnchorStyles.Left);
RegistersGrid.DataSource = dt;
RegistersGrid.Dock = (DockStyle)2;
//
// RemoveButtonRegistersGrid
//
RemoveButton.BackColor = System.Drawing.Color.Red;
RemoveButton.Location = new System.Drawing.Point(3, 4);
RemoveButton.Name = "RemoveButton";
RemoveButton.Size = new System.Drawing.Size(75, 25);
RemoveButton.TabIndex = 0;
RemoveButton.Text = "Remove";
RemoveButton.UseVisualStyleBackColor = false;
RemoveButton.Click += new System.EventHandler(this.RemoveButton_Click);
//
// ResizeButton
//
ResizeButton.BackColor = System.Drawing.Color.DarkOrange;
ResizeButton.Location = new System.Drawing.Point(81, 4);
ResizeButton.Name = "ResizeButton";
ResizeButton.Size = new System.Drawing.Size(75, 25);
ResizeButton.TabIndex = 6;
ResizeButton.Text = "Resize";
ResizeButton.UseVisualStyleBackColor = false;
ResizeButton.Click += new System.EventHandler(this.ResizeButton_Click);
//
// SerialNolabel
//
SerialNolabel.AutoSize = true;
SerialNolabel.Location = new System.Drawing.Point(159, 10);
SerialNolabel.Name = "SerialNolabel";
SerialNolabel.Size = new System.Drawing.Size(53, 13);
SerialNolabel.TabIndex = 4;
SerialNolabel.Text = "Serial No:";
//
// SerialNoTB
//
SerialNoTB.Location = new System.Drawing.Point(215, 7);
SerialNoTB.Name = "SerialNoTB";
SerialNoTB.Size = new System.Drawing.Size(100, 20);
SerialNoTB.TabIndex = 1;
//
// VersionLabel
//
VersionLabel.AutoSize = true;
VersionLabel.Location = new System.Drawing.Point(318, 10);
VersionLabel.Name = "VersionLabel";
VersionLabel.Size = new System.Drawing.Size(45, 13);
VersionLabel.TabIndex = 5;
VersionLabel.Text = "Version:";
//
// VersionTB
//
VersionNoTB.Location = new System.Drawing.Point(366, 7);
VersionNoTB.Name = "VersionTB";
VersionNoTB.Size = new System.Drawing.Size(100, 20);
VersionNoTB.TabIndex = 2;
page.Controls.Add(ResizeButton);
page.Controls.Add(RemoveButton);
page.Controls.Add(VersionLabel);
page.Controls.Add(VersionNoTB);
page.Controls.Add(SerialNolabel);
page.Controls.Add(SerialNoTB);
page.Controls.Add(RegistersGrid);
page.Location = new System.Drawing.Point(4, 22);
page.Size = new System.Drawing.Size(716, 554);
page.TabIndex = 1;
page.UseVisualStyleBackColor = true;
page.Update(); // the following code fails
int k = dt.Columns.Count;
int l = RegistersGrid.ColumnCount;
for (int j = 0; j <= RegistersGrid.ColumnCount - 1; j++)
RegistersGrid.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
RegistersGrid.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
//datagrid has calculated it's widths so we can store them
for (int i = 0; i <= RegistersGrid.ColumnCount - 1; i++)
{
int colw = RegistersGrid.Columns[i].Width; //store autosized widths
RegistersGrid.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; //remove autosizing
RegistersGrid.Columns[i].Width = colw; //set width to calculated by autosize
}
}
}

How to find specific dynamic control and get value

I am making student attendance system. I am creating dynamic control and assigning values from database. Now I want to know how to find desired dynamic control and how I will get value from it.
I don't know how I can find desired control using a foreach loop.
This is my code for creating dynamic controls.
public void genControl(StudentAttendence sta)
{
StudentAttendenceBSLDAL stabd = new StudentAttendenceBSLDAL();
List<string[]> liName = stabd.takStudent(sta);
counts = Convert.ToInt16(stabd.takStudent(sta).Count);
for (int i=0; i< stabd.takStudent(sta).Count;i++)
{
for(int j = 0; j<liName[i].Count();j++)
{
Label lblStudentname = new Label();
Label lblStId = new Label();
lblStId.Name = "lblStId"+i.ToString()+j.ToString();
lblStudentname.Name = "liName"+i.ToString()+j.ToString();
lblStId.AutoSize = true;
lblStudentname.AutoSize = true;
if (j==0)
{
lblStId.Text = liName[i][j].ToString();
}
if(j==1)
{
lblStudentname.Text = liName[i][j].ToString();
}
lblStId.AutoSize = true;
lblStudentname.AutoSize = true;
if (i == 1)
{
lblStId.Location = new Point(41, 229);
lblStudentname.Location = new Point(153, 7);
}
else
{
lblStId.Location = new Point(3, 7 + 20);
lblStudentname.Location = new Point(153, 7 + 20);
}
this.Controls.Add(lblStId);
panel1.Controls.Add(lblStudentname);
}
CheckBox cba = new CheckBox();
cba.Name = "cba" + i.ToString() ;
cba.Text = "A";
cba.AutoSize = true;
CheckBox cbp = new CheckBox();
cbp.Name = i.ToString() ;
cbp.Text = "P";
cbp.AutoSize = true;
CheckBox cbl = new CheckBox();
cbl.Name = "cbl" + i.ToString() ;
cbl.Text = "L";
cbl.AutoSize = true;
if (i == 1)
{
cbp.Location = new Point(590, 3);
cba.Location = new Point(631, 3);
cbl.Location = new Point(670, 3);
}
else
{
cbp.Location = new Point(590, 3 + 23);
cba.Location = new Point(631, 3 + 23);
cbl.Location = new Point(670, 3 + 23);
}
panel1.Controls.Add(cbp);
panel1.Controls.Add(cba);
panel1.Controls.Add(cbl);
}
}
This is button control event in which I am trying to find control and get it value.
private void button2_Click(object sender, EventArgs e)
{
StudentAttendence sta = new StudentAttendence();
StudentAttendenceBSLDAL stabd = new StudentAttendenceBSLDAL();
// List<string[]> liName = stabd.takStudent(sta);
for (int i=0;i<counts;i++)
{
CheckBox cbP = panel1.Controls.OfType<CheckBox>().FirstOrDefault(b => b.Name.Equals("cbp"+i.ToString()));
// Label stid = panel1.Controls.Find("lblStId" + i.ToString(), false).First() as Label;
if(!cbP.IsChecked)
{
MessageBox.Show("control found");
}
}
}
You can save your control list into a SortedList.
You can use this sorted list for further processing

Looping through labels with similar name C#

I want to change the background of some labels depending on what is written on a text file:
private void Form3_Load(object sender, EventArgs e)
{
string[] words = new string[7];
StreamReader read = new StreamReader(path);
while(!read.EndOfStream)
{
string line = read.ReadLine();
words = line.Split(';');
if(words[6] == "no")
{
//-----What I have to write here---
}
}
read.Close();
}
There are over 50 labels named "lbl101","lbl102","....","lbl150"
try it:
if(words[6] == "no")
{
int count = 150;
for (int a = 1 ; a < count; a++)
{
Label currentLabel = (Label)this.Controls.Find("lbl"+a,true)[0];
//change color of currentLabel
}
}
There's the working solution:
private void Form3_Load(object sender, EventArgs e)
{
int count = 101;
string[] words = new string[7];
StreamReader read = new StreamReader(pathRooms);
while(!read.EndOfStream)
{
string line = read.ReadLine();
words = line.Split(';');
if (words[6] == "no")
{
Label currentLabel = (Label)this.Controls.Find("lbl" + count, true)[0];
currentLabel.BackColor = Color.Yellow;
}
count = count + 1;
}
read.Close();
}
You can iterate all over them using OfType<T>() method on Controls collection of form like:
if(words[6] == "no")
{
foreach(var label in this.Controls.OfType<Label>().Where(x=>x.Name.Contains("lbl")))
{
label.Text = "Some Text";
}
}
This will only work on the labels that are direct child of form, labels nested inside other user controls or nested panels will not be affected, for that you have to do it recursively.
Loop through the Controls collection of the form checking for Label objects. Then, amend accordingly as per the specified value.
1.) Create a List with all the labels.
Label lbl101 = new Label();
Label lbl102 = new Label();
...
List<Label> labels = new List<Label>()
{
lbl101,
lbl102
...
};
2.) If your words[] string is the name of the color you can write:
if(words[6] == "no")
{
System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml(words[..]);
foreach(Label l in Labels)
{
l.BackColor = myColor;
}
}

ASP.Net Dynamic Gridview with custom ItemTemplate

I need some help in rendering a dynamic gridview.
Using the source code below, I can add the grid to the page and it generates one row for each entry in the datasource.
The problem is that the controls only appears in the last row. If I add another entry to the datasource, I get one more row in the Gridview but only the last is showing the controls that I've added using the ItemTemplate.
When I debug the solution I can see that it instatiates a new ItemTemplate foreach collumn and that it adds all the controls, but after the databinding of the grid, all the cells are empty, except the ones of the last row.
Please help if you can. Thanks
private void BuildGridInterface()
{
TBL_PARAM_01 xpto = new TBL_PARAM_01();
GridView grid = new GridView();
grid.ID = "grd";
grid.AutoGenerateColumns = false;
grid.ShowHeader = true;
PropertyInfo[] props = xpto.GetType().GetProperties();
foreach (PropertyInfo info in props)
{
TemplateField field = new TemplateField();
object[] attributes = info.GetCustomAttributes(true);
var att = attributes.SingleOrDefault(a => a.GetType() == typeof(Domain));
WebControl control;
if (att != null)
{
control = new DropDownList();
control.ID = "drp" + info.Name;
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXXX", Value = "1" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX2", Value = "2" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX3", Value = "3" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX4", Value = "4" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX5", Value = "5" });
((DropDownList)control).Items.Add(new ListItem() { Text = "XXXX6", Value = "6" });
}
else
{
control = new TextBox();
control.ID = "txt" + info.Name;
}
field.ItemTemplate = new ItemTemplate(control, false, info.Name);
field.HeaderText = ((MatrixFieldLabel)attributes.Single(a => a.GetType() == typeof(MatrixFieldLabel))).Value;
grid.Columns.Add(field);
}
FillGrid(grid);
placer.Controls.Add(grid);
}
public class ItemTemplate : ITemplate
{
WebControl Control { get; set; }
bool Enabled { get; set; }
string ColumName { get; set; }
public ItemTemplate(WebControl control, bool enabled, string columname)
{
this.Control = control;
this.Enabled = enabled;
this.ColumName = columname;
control.DataBinding += new EventHandler(Control_DataBinding);
}
public void InstantiateIn(Control container)
{
((WebControl)container).Enabled = Enabled;
container.Controls.Add(this.Control);
}
void Control_DataBinding(object sender, EventArgs e)
{
GridViewRow container = (GridViewRow)((Control)sender).NamingContainer;
object dataValue = DataBinder.Eval(container.DataItem, this.ColumName);
if (sender.GetType() == typeof(TextBox))
((TextBox)sender).Text = dataValue.ToString();
else if (sender.GetType() == typeof(DropDownList))
((DropDownList)sender).SelectedValue = dataValue.ToString();
}
private void FillGrid(GridView target)
{
List<TBL_PARAM_01> list = new List<TBL_PARAM_01>();
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 1, IDEntityRecordX = 2, Output = "XPTO 3" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 2, IDEntityRecordX = 3, Output = "XPTO 4" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 3, IDEntityRecordX = 4, Output = "XPTO 5" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 4, IDEntityRecordX = 5, Output = "XPTO 6" });
list.Add(new TBL_PARAM_01() { IDEntityRecordProduct = 5, IDEntityRecordX = 6, Output = "XPTO 7" });
target.DataSource = list;
target.DataBind();
}
}
Problem solved. I've had to rewrite the method InstantiateIn of my ItemTemplate class.
Thanks.
you appear to be replacing the datasource for your target gridview every time you call FillGrid, and rebinding it. You could remove your DataSource assignment and DataBind calls outside of the FillGrid method and between FillGrid(grid); and placer.Controls.Add(grid); lines in the BuildGridInterface method?
Let us know if that helps.. :)

Categories