Referencing a newly created control - c#

If i create a control on the fly, as below
private void button10_Click(object sender, EventArgs e)
{
CheckedListBox CheckedListBox1 = new CheckedListBox();
CheckedListBox1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(224)), ((System.Byte)(192)));
CheckedListBox1.ItemHeight = 16;
CheckedListBox1.Location = new System.Drawing.Point(12, 313);
CheckedListBox1.Name = "CheckedListBox1";
CheckedListBox1.Size = new System.Drawing.Size(168, 244);
CheckedListBox1.TabIndex = 0;
Controls.Add(CheckedListBox1);
Button button12 = new Button();
button12.Location = new Point(900, 500);
button12.Size = new Size(75, 23);
button12.Click += new System.EventHandler(button12_Click);
button12.Name = "button12";
button12.Text = "Toggle All";
Controls.Add(button12);
}
what is the best way to reference that control from a function outside of the local scope? would it be best creating a static class to somehow hold a reference to the control that can be accessed outside the local scope or is there a findcontrol function for winforms ( i think findcontrol is just for web).
i want
private void button12_Click(object sender, EventArgs e)
{
for (int i = 0; i <= (CheckedListBox1.Items.Count - 1); i++)
{
if (CheckedListBox1.GetItemCheckState(i) == CheckState.Checked)
{
CheckedListBox1.SetItemCheckState(i, CheckState.Indeterminate);
}
else if (CheckedListBox1.GetItemCheckState(i) == CheckState.Indeterminate)
{
CheckedListBox1.SetItemCheckState(i, CheckState.Checked);
}
}
}
to be able to work but im going wrong because of scope? pls help a newbie
thanks

I'm assuming the two functions button12_Click and button10_Click are members of a From class. In this case, your should make your CheckListBox1 and button12 members of the From class. That way, the button12_Click will be able to reference the controls you will have created.
public partial class Form1 : Form
{
CheckedListBox CheckedListBox1 = null;
Button button12 = null;
private void button10_Click(object sender, EventArgs e)
{
CheckedListBox1 = new CheckedListBox();
CheckedListBox1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(224)), ((System.Byte)(192)));
CheckedListBox1.ItemHeight = 16;
CheckedListBox1.Location = new System.Drawing.Point(12, 313);
CheckedListBox1.Name = "CheckedListBox1";
CheckedListBox1.Size = new System.Drawing.Size(168, 244);
CheckedListBox1.TabIndex = 0;
Controls.Add(CheckedListBox1);
button12 = new Button();
button12.Location = new Point(900, 500);
button12.Size = new Size(75, 23);
button12.Click += new System.EventHandler(button12_Click);
button12.Name = "button12";
button12.Text = "Toggle All";
Controls.Add(button12);
}
private void button12_Click(object sender, EventArgs e)
{
for (int i = 0; i <= (CheckedListBox1.Items.Count - 1); i++)
{
if (CheckedListBox1.GetItemCheckState(i) == CheckState.Checked)
{
CheckedListBox1.SetItemCheckState(i, CheckState.Indeterminate);
}
else if (CheckedListBox1.GetItemCheckState(i) == CheckState.Indeterminate)
{
CheckedListBox1.SetItemCheckState(i, CheckState.Checked);
}
}
}
}

When there is only one CheckedListBox make it a class variable. But when you have always only one CheckedListBox - why do you create it dynamically?

If you're adding the controls to the page's Controls collection, just go look there. If you know the index of the control you can reference it that way. if you're adding the control to some container's Control's collection (say, a panel), look for it there

Related

How to create MaterialSingleLineTextField Controls dynamically

I would like to add MaterialSingleLineTextField dynamically to a Form.
I have used MaterialSkin NuGet package:
I am trying to create multiple MaterialSkin TextBoxes dynamically on Form.Load. But no Controls are displaying in the hosing Panel.
private void Form1_Load(object sender, EventArgs e)
{
int n = 5;
int pointX = 30;
int pointY = 40;
//panel1.Controls.Clear();
for (int i = 0; i < n - 1; i++)
{
MaterialSingleLineTextField a = new MaterialSingleLineTextField();
a.Text = (i + 1).ToString();
a.Visible = true;
a.Location = new Point(pointX, pointY);
panel1.Controls.Add(a);
panel1.Show();
pointY += 20;
}
}
This code block works perfectly fine for normal TextBoxes.
Is there any way to add MaterialSingleLineTextField dynamically?
A sample Form initialization with default Theme values.
The MaterialSkinManager is initialized in the Form Constructor, setting the Theme to MaterialSkinManager.Themes.LIGHT and default color scheme. The Form base Type is set to MaterialForm.
A specified number of MaterialSingleLineTextField controls is added to a parent container (a Panel), starting from a defined Location downwards.
These Controls are anchored to the parent and the Height is set to Parent.Font.Height + 4.
It's important that you specify the Size of these Controls, otherwise you'll get a minimal size that prevents the Controls from showing their content.
As you can see in the AddTextFields() method, it's important that you dispose of the previous Controls added to the Parent container, if you want to replace the existing with new ones. Even more important using this Library.
Calling the Clear() method of a Control.Controls collection (as in the line you have commented out) doesn't dispose of anything, those controls are still alive.
public partial class Form1 : MaterialForm
{
private readonly MaterialSkinManager msManager = null;
public Form1()
{
InitializeComponent();
msManager = MaterialSkinManager.Instance;
msManager.AddFormToManage(this);
msManager.Theme = MaterialSkinManager.Themes.LIGHT;
}
private void Form1_Load(object sender, EventArgs e)
{
AddTextFields(panel1, 5, new Point(30, 10), false);
}
private void AddTextFields(Control parent, int controlsCount, Point startPosition, bool ClearExisting)
{
if (clearExisting && parent.Controls.Count > 0) {
for (int i = parent.Controls.Count - 1; i >= 0; i--) {
parent.Controls[i].Dispose();
}
}
int controlHeight = parent.Font.Height + 4;
int yIncrement = 0;
for (int i = 0; i < controlsCount; i++) {
var textField = new MaterialSingleLineTextField() {
Text = (i + 1).ToString(),
Size = new Size(parent.ClientSize.Width - startPosition.X - 4, controlHeight),
Location = new Point(startPosition.X, startPosition.Y + yIncrement),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right
};
parent.Controls.Add(textField);
yIncrement += (controlHeight + 10);
}
}
private void matBtnChangeTheme_Click(object sender, EventArgs e)
{
msManager.Theme = MaterialSkinManager.Themes.DARK;
msManager.ColorScheme = new ColorScheme(Primary.Blue600, Primary.Blue900, Primary.Blue500, Accent.LightBlue200, TextShade.WHITE);
}
private void matBtnAddControls_Click(object sender, EventArgs e)
{
AddTextFields(panel1, 7, new Point(30, 10), true);
}
}
Sample functionality:

Adding Event Handler for Dynamically Created to window Form

I have a window form where I am creating a list of Checkboxes. The number of checkboxes created are based upon how many items are returned from the database. I've been able to create the checkboxes; however, I am not sure how to add event handlers for these checkboxes. For example, I'd like to add an OnCheckedChanged or CheckStateChanged event. How can I add these events? Also, I would appreciate any other suggestion. I am a total newbie to programming.
private void Form1_Load(object sender, EventArgs e)
{
CheckBoxes = new CheckBox[listGroup.Count()];
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i]+"_CheckedChanged");
CheckBoxes[i].Width = 200;
if (i == 0)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 10);
}
else if (i == 1)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 40);
}
else if (i == 2)
{
CheckBoxes[i].Location = new System.Drawing.Point(5, 80);
}
this.Controls.Add(CheckBoxes[i]);
}
}
private void Form1_Load(object sender, EventArgs e)
{
//...
CheckBoxes[i].CheckedChanged += checkBoxes_CheckedChanged;
CheckBoxes[i].CheckStateChanged += checkBoxes_CheckStateChanged;
}
void checkBoxes_CheckedChanged(object sender, EventArgs e)
{ //do stuff when checked changed }
void checkBoxes_CheckStateChanged(object sender, EventArgs e)
{ //do stuff when check state changed }
Note: this will give identical event handling for all of your checkboxes.
If you want to do different things for different textboxes, you have to name the eventhandler differently and define that eventhandler.
A more efficient way to set the location of your checkboxes
for (int i = 0; i < listGroup.Count(); i++)
{
CheckBoxes[i] = new CheckBox();
CheckBoxes[i].Text = listGroup.ElementAt(i).GroupName;
CheckBoxes[i].Name = "txt" + listGroup.ElementAt(i).GroupName.Replace(' ', '_');
CheckBoxes[i].CheckedChanged += new EventHandler(CheckBoxes[i] + "_CheckedChanged");
CheckBoxes[i].Width = 200;
//set location based on index of i
CheckBoxes[i].Location = new System.Drawing.Point(5, 10 + (i * 30));
this.Controls.Add(CheckBoxes[i]);
}
private void LoadNewCheckboxes()
{
dynamic listGroupCount = 10;
List<System.Windows.Forms.CheckBox> CheckBoxes = new List<System.Windows.Forms.CheckBox>();
for (int i = 0; i <= listGroupCount - 1; i++)
{
System.Windows.Forms.CheckBox chkbox = new System.Windows.Forms.CheckBox();
chkbox.Text = i.ToString();
//listGroup.ElementAt(i).GroupName
chkbox.Name = "txt" + i.ToString();
//listGroup.ElementAt(i).GroupName.Replace(" "c, "_"c)
chkbox.CheckedChanged += new EventHandler(chkbox_CheckedChanged);
chkbox.CheckStateChanged += new EventHandler(chkbox_CheckStateChanged);
chkbox.Width = 200;
chkbox.AutoSize = true;
this.Controls.Add(chkbox);
CheckBoxes.Add(chkbox);
if (i == 0)
{
chkbox.Location = new System.Drawing.Point(5, 10);
}
else
{
chkbox.Location = new System.Drawing.Point(5, (CheckBoxes[i - 1].Top + CheckBoxes[i - 1].Height + 10));
}
}
}
private void chkbox_CheckedChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckedChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}
private void chkbox_CheckStateChanged(object sender, EventArgs e)
{
System.Windows.Forms.CheckBox chkbox = (System.Windows.Forms.CheckBox)sender;
if (chkbox != null)
{
//do somthing
Debug.WriteLine("chkbox_CheckStateChanged");
Debug.WriteLine(chkbox.Text);
Debug.WriteLine(chkbox.Checked.ToString());
Debug.WriteLine(chkbox.Name.ToString());
}
}

Removing TextBoxes created Dynamically on Button click

I have tried creating textboxes dynamically using lists. All i need now is, how can i reset all text boxes that i have created by hitting a reset button.
The following is my code:
public void button2_Click_1(object sender, EventArgs e)
{
int number = Convert.ToInt32(textBox2.Text);
List<TextBox> inputTextBoxes;
inputTextBoxes = new List<TextBox>();
for (int i = 1; i <= number; i++)
{
Label labelInput = new Label();
TextBox textBoxNewInput = new TextBox();
labelInput.Text = "Activity No: " + i;
labelInput.Location = new System.Drawing.Point(30, textBox2.Bottom + (i * 40));
labelInput.AutoSize = true;
textBoxNewInput.Location = new System.Drawing.Point(labelInput.Width+60, labelInput.Top - 3);
inputTextBoxes.Add(textBoxNewInput);
this.Controls.Add(labelInput);
this.Controls.Add(textBoxNewInput);
}
}
The answer is:
private void resetButton_Click(object sender,EventArgs e)
{
for (int i = 0; i <= inputTextBoxes.Length; i++)
{
inputTextBoxes[i].Text = "";
}
}
And you should declare inputTextBoxes is a class member which is same class' of buttons.
Move the following line outside the event handler function (outside the function but inside the class)
List<TextBox> inputTextBoxes;
Then on the reset button click
private void btnReset_Click(object sender, EventArgs e)
{
foreach(TextBox txt in inputTextBoxes)
{
this.Controls.Remove(txt);
}
inputTextBoxes.Clear();
}
Edit: Corrected the class type in foreach loop (from Button to TextBox)

Array of buttons: change property

I have an array of buttons, like this:
int x = 0, y = 0;
butt2 = new Button[100];
for (int i = 0; i < 100; i++)
{
butt2[i] = new Button();
int names = i;
butt2[i].Name = "b2" + names.ToString();
butt2[i].Location = new Point(525 + (x * 31), 70 + (y * 21));
butt2[i].Visible = true;
butt2[i].Size = new Size(30, 20);
butt2[i].Click += new EventHandler(butt2_2_Click); //problem lies here (1)
this.Controls.Add(butt2[i]);
}
private void butt2_2_Click(object sender, EventArgs e)
{
// want code here
}
I want to change the back color of the button when clicked. I was thinking of passing i to be able to do this:
butt2[i].BackColor = Color.Green;
This should do the trick:
private void butt2_2_Click(object sender, EventArgs e)
{
Button pushedBtn = sender as Button;
if(pushedBtn != null)
{
pushedBtn.BackColor = Color.Green;
}
}
And this holds for most UI events, the 'object sender' parameter refers to the control that 'sent'/'fired' the event.
To learn more about C# event handling, I would start here.
Also, here is a SO question about GUI event handling, answered nicely by Juliet (accepted answer).
Hope this helps.

Dynamically Created Combobox's SelectedIndexChanged Event

i'm designing a windows form application. In this app, user selects a number from a combobox, then depending on the number, some dynamic controls will be created(labels and comboboxes).
My problem is, i need to write some code on these dynamically created comboboxs' "selectedindexchanged" event. But i don't know how to create an event to dynamic combobox.
Here is my function:
FORM1.CS
public void getchildCntrl(Panel pnl,ComboBox cmbb)
{
for (int ix = pnl.Controls.Count - 1; ix >= 0; ix--)
if (pnl.Controls[ix].Name.Substring(0, 5) == "Child") pnl.Controls[ix].Dispose();
if (cmbb.SelectedIndex != 0)
{
Label[] childLabels = new Label[cmbb.SelectedIndex];
ComboBox[] txtTeamNames = new ComboBox[cmbb.SelectedIndex];
for (int i = 0; i < txtTeamNames.Length; i++)
{
//label create
var lbl = new Label();
childLabels[i] = lbl;
lbl.Name = "ChildLb" + i.ToString();
lbl.Text = (i + 1).ToString() + ". Çocuk-Yaş :";
lbl.Width = 80;
lbl.Location = new Point(cmbb.Location.X - 85, cmbb.Location.Y + 7 + ((i + 1) * 28));
lbl.Visible = true;
pnl.Controls.Add(lbl);
//combobox create
var cmb = new ComboBox();
txtTeamNames[i] = cmb;
cmb.Name = "Child" + i.ToString();
cmb.Location = new Point(cmbb.Location.X, cmbb.Location.Y + 5 + ((i + 1) * 28));
cmb.Width = 40;
cmb.DropDownStyle = ComboBoxStyle.DropDownList;
cmb.DataSource = ages.ToArray();
cmb.Visible = true;
pnl.Controls.Add(cmb);
}
}
}
You just register to the event like below...
cmb.SelectedIndexChanged += new System.EventHandler((object o, EventArgs e) =>
{
//Do something here
});
Or
cmb.SelectedIndexChanged += new System.EventHandler(cmb_SelectedValueChanged);
private void cmb_SelectedValueChanged(object sender, EventArgs e)
{
//Do something here.
}
You can hook up an event handler to the ComboBox like this:
cmd.SelectionChanged += new SelectionChangedEventHandler(GuiController_SelectionChanged);
void GuiController_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
throw new NotImplementedException();
}
Register event handler this way:
cmb.SelectedIndexChanged+=new EventHandler(cmb_SelectedIndexChanged);
Unregister this way:
cmb.SelectedIndexChanged-=new EventHandler(cmb_SelectedIndexChanged);
private void cmb_SelectedIndexChanged(object sender, System.EventArgs e)
{
//write your event code here
}
How to: Create Event Handlers at Run Time for Windows Forms
public void getchildCntrl(Panel pnl,ComboBox cmbb)
{
//// your code.....
//combobox create
var cmb = new ComboBox();
cmb.SelectedIndexChanged+=new EventHandler(cmb_SelectedIndexChanged);
// remaining code
cmb.Visible = true;
pnl.Controls.Add(cmb);
}
}
}
For specifying parameters - go through:
ComboBox.SelectedIndexChanged Event

Categories

Resources