Dynamically Adding Class of Controls - c#

I am having trouble with dynamically adding a class of controls that should when working look like this:
When a new one is added it should appear in the left panel under the toolstrip.
So far I am having trouble making them appear (The one in the middle is just the design I made).
Here is the code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//Problem Occurs Here
EquationBox[] EquationBoxArray = new EquationBox[12];
for (int x = 0; x < 12; x++)
{
EquationBoxArray[x] = new EquationBox();
ActiveForm.Controls.Add(EquationBoxArray[x].mainPanel);
ActiveForm.Controls.Add(EquationBoxArray[x].colorPanel);
}
}
private void add_line_Click(object sender, EventArgs e) //Add Line
{
}
private void clear_Click(object sender, EventArgs e) //Clear Lines
{
}
}
public class EquationBox
{
public Panel colorPanel = new Panel();
public Panel mainPanel = new Panel();
public TextBox equationBox = new TextBox();
public CheckBox isVisibleBox = new CheckBox();
public EquationBox()
{
mainPanel.Size = new Size(200, 72);
colorPanel.Size = new Size(33, 72);
mainPanel.Location = new Point(50, 50);
colorPanel.Location = new Point(50, 50);
colorPanel.BackColor = Color.Red;
}
}
The problem occurs here:
//Problem Occurs Here
EquationBox[] EquationBoxArray = new EquationBox[12];
for (int x = 0; x < 12; x++)
{
EquationBoxArray[x] = new EquationBox();
ActiveForm.Controls.Add(EquationBoxArray[x].mainPanel);
ActiveForm.Controls.Add(EquationBoxArray[x].colorPanel);
}
When I run it, it return with:
Additional information: Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
And even before that started happening, the EqautionBox wouldn't appear.
Thanks in advance, this is really troubling me.
For the constructor of EquationBox:
public EquationBox()
{
mainPanel.Size = new Size(200, 72);
colorPanel.Size = new Size(33, 72);
mainPanel.Location = new Point(50, 50);
colorPanel.Location = new Point(50, 50);
colorPanel.BackColor = Color.Red;
}

First, your control appeared, but mainPanel is overlap colorPanel and you can't see mainPanel (same BG color as your form), so swap which added first solved
EquationBox[] EquationBoxArray = new EquationBox[12];
for (int x = 0; x < 12; x++)
{
EquationBoxArray[x] = new EquationBox();
this.Controls.Add(EquationBoxArray[x].colorPanel);
this.Controls.Add(EquationBoxArray[x].mainPanel);
}
I am using this.Controls, not sure about the ActiveForm.Controls part, maybe on constructing, your Form1 is not the active one, so error occured.
Ps: I suggest add colorPanel to mainPanel, and only add mainPanel to Form. And UserControl is a good solution here as Steve Wellens said.

There are various issues with EquationBox the TextBox and CheckBox are not in the panel. It would be easier to make it a UserControl.
Then to do the positioning use a FlowLayoutPanel.

Related

C# Custom ComboBox - DropDown Position

I'm creating a ComboBox control using ToolStripControlHost and ToolStripDropDown that can host any kind of control in the DropDown window. For example, the DropDown window might display a listview or treeview or even another usercontrol.
I'm posting a simplified code below where dropdown host a usercontrol with a listview and a button like this:
The problem occurs when the control is positioned at the bottom of the screen in such a way that the dropdown window will extrapolate the lower boundary of the screen. When this occurs, the dropdown ends up hiding the control.
In this case, I'd like to fix the _dropDown.Show method call to show dropdown window as follows:
To repeat the problem, just run the code below and drag the window to the bottom of the screen and open the dropdown.
using System;
using System.Windows.Forms;
public class CustomComboBox : UserControl
{
ToolStripDropDown _dropDown;
public CustomComboBox()
{
var textbox = new TextBox();
textbox.Location = new System.Drawing.Point(0, 0);
textbox.Size = new System.Drawing.Size(this.Width - 22, 20);
textbox.Anchor = AnchorStyles.Left | AnchorStyles.Right | AnchorStyles.Top;
this.Controls.Add(textbox);
var button = new Button();
button.Location = new System.Drawing.Point(this.Width - 22, -1);
button.Size = new System.Drawing.Size(22, 22);
button.Text = "\u2BC6";
button.Anchor = AnchorStyles.Right | AnchorStyles.Top;
button.Click += new System.EventHandler(this.Button_Click);
this.Controls.Add(button);
var dropDownControl = new DropDownControlTest();
var controlHost = new ToolStripControlHost(dropDownControl);
_dropDown = new ToolStripDropDown();
_dropDown.AutoSize = true;
_dropDown.Items.Add(controlHost);
}
void Button_Click(object sender, EventArgs e)
{
_dropDown.Show(this, 0, this.Height);
}
}
public class DropDownControlTest : UserControl
{
public DropDownControlTest()
{
var listview = new ListView();
listview.Location = new System.Drawing.Point(3, 1);
listview.Size = new System.Drawing.Size(400,300);
listview.View = View.Details;
listview.Columns.Add("Col 1",100);
listview.Columns.Add("Col 2",100);
this.Controls.Add(listview);
var button = new Button();
button.Location = new System.Drawing.Point(3, 305);
button.Text = "More...";
this.Controls.Add(button);
}
}
public class Form1 : Form
{
private static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
public Form1 ()
{
CustomComboBox ccBox = new CustomComboBox();
ccBox.Location = new System.Drawing.Point(10, 10);
ccBox.Height = 20;
this.Text = "Test CustomComboBox";
this.Controls.Add(ccBox);
}
}
You can use the ToolStripDropDown.Show Method (Control, Point, ToolStripDropDownDirection) overload to control the drop direction. The code will need to perform bounds checking to decide whether to place the dropdown above or below the textbox.
The following is a simplistic method for doing the bounds checking and was only tested on a single screen configuration.
First, make textbox a class level variable.
private TextBox textbox;
public CustomComboBox()
{
//var textbox = new TextBox();
textbox = new TextBox();
The display logic is as follows.
void Button_Click(object sender, EventArgs e)
{
Point textBoxScreenLocation = textbox.PointToScreen(textbox.Location);
// try to position _dropDown below textbox
Point pt = textBoxScreenLocation;
pt.Offset(0, textbox.Height);
// determine if it will fit on the screen below the textbox
Size dropdownSize = _dropDown.GetPreferredSize(Size.Empty);
Rectangle dropdownBounds = new Rectangle(pt, dropdownSize);
if (dropdownBounds.Bottom <= Screen.GetWorkingArea(dropdownBounds).Bottom)
{ // show below
_dropDown.Show(pt, ToolStripDropDownDirection.BelowRight);
}
else
{ // show above
_dropDown.Show(textBoxScreenLocation, ToolStripDropDownDirection.AboveRight);
}
}
}
I can not comment that is why I am answering your question. You can use the reflection and then re-position you control. I have found a custom combobox control same as you developed. Please check this. At least, you will get some idea what you need to do.

Converting windows Form to windows Metro Form

i have written a desktop app in normal windows form, it worked fine. Later i tried to convert it to Metro form because of its modern look. With minor change in control names i used most of the code from old normal form. But the form resizing function block throwing "System.NullReferenceException" while starting the app. But after commenting the resizing event it works fine.
private void Form1_Load(object sender, EventArgs e)
{
defaultSize = this.Size;
panel4Size = new Rectangle[] { new Rectangle(panel4.Location.X, panel4.Location.Y, panel4.Width, panel4.Height), new Rectangle(qusNo.Location.X, qusNo.Location.Y, qusNo.Width, qusNo.Height), new Rectangle(element1.Location.X, element1.Location.Y, element1.Width, element1.Height), new Rectangle(element2.Location.X, element2.Location.Y, element2.Width, element2.Height), new Rectangle(operation.Location.X, operation.Location.Y, operation.Width, operation.Height), new Rectangle(line.Location.X, line.Location.Y, line.Width, line.Height), new Rectangle(nextQus.Location.X, nextQus.Location.Y, nextQus.Width, nextQus.Height), new Rectangle(flp1.Location.X, flp1.Location.Y, flp1.Width, flp1.Height), new Rectangle(flp2.Location.X, flp2.Location.Y, flp2.Width, flp2.Height), new Rectangle(opt1.Location.X, opt1.Location.Y, opt1.Width, opt1.Height), new Rectangle(opt2.Location.X, opt2.Location.Y, opt2.Width, opt2.Height), new Rectangle(opt3.Location.X, opt3.Location.Y, opt3.Width, opt3.Height), new Rectangle(opt4.Location.X, opt4.Location.Y, opt4.Width, opt4.Height), new Rectangle(opt5.Location.X, opt5.Location.Y, opt5.Width, opt5.Height), new Rectangle(opt6.Location.X, opt6.Location.Y, opt6.Width, opt6.Height), new Rectangle(dopt1.Location.X, dopt1.Location.Y, dopt1.Width, dopt1.Height), new Rectangle(dopt2.Location.X, dopt2.Location.Y, dopt2.Width, dopt2.Height), new Rectangle(dopt3.Location.X, dopt3.Location.Y, dopt3.Width, dopt3.Height), new Rectangle(dopt4.Location.X, dopt4.Location.Y, dopt4.Width, dopt4.Height), new Rectangle(dopt5.Location.X, dopt5.Location.Y, dopt5.Width, dopt5.Height), new Rectangle(dopt6.Location.X, dopt6.Location.Y, dopt6.Width, dopt6.Height), new Rectangle(LaBackBt.Location.X, LaBackBt.Location.Y, LaBackBt.Width, LaBackBt.Height), new Rectangle(LaFinishBt.Location.X, LaFinishBt.Location.Y, LaFinishBt.Width, LaFinishBt.Height), new Rectangle(results.Location.X, results.Location.Y, results.Width, results.Height) };
panel2Size = new Rectangle[] { new Rectangle(panel2.Location.X, panel2.Location.Y, panel2.Width, panel2.Height), new Rectangle(Easy.Location.X, Easy.Location.Y, Easy.Width, Easy.Height), new Rectangle(Hard.Location.X, Hard.Location.Y, Hard.Width, Hard.Height), new Rectangle(MdBackBt.Location.X, MdBackBt.Location.Y, MdBackBt.Width, MdBackBt.Height), new Rectangle(eelem1.Location.X, eelem1.Location.Y, eelem1.Width, eelem1.Height), new Rectangle(eelem2.Location.X, eelem2.Location.Y, eelem2.Width, eelem2.Height), new Rectangle(eelem3.Location.X, eelem3.Location.Y, eelem3.Width, eelem3.Height), new Rectangle(eelem4.Location.X, eelem4.Location.Y, eelem4.Width, eelem4.Height), new Rectangle(eelem5.Location.X, eelem5.Location.Y, eelem5.Width, eelem5.Height), new Rectangle(flp3.Location.X, flp3.Location.Y, flp3.Width, flp3.Height), new Rectangle(flp4.Location.X, flp4.Location.Y, flp4.Width, flp4.Height), new Rectangle(flp5.Location.X, flp5.Location.Y, flp5.Width, flp5.Height), new Rectangle(flp6.Location.X, flp6.Location.Y, flp6.Width, flp6.Height) };
panel1Size = new Rectangle[] { new Rectangle(panel1.Location.X, panel1.Location.Y, panel1.Width, panel1.Height), new Rectangle(label1.Location.X, label1.Location.Y, label1.Width, label1.Height), new Rectangle(listView3.Location.X, listView3.Location.Y, listView3.Width, listView3.Height), new Rectangle(HmAdd.Location.X, HmAdd.Location.Y, HmAdd.Width, HmAdd.Height), new Rectangle(HmSub.Location.X, HmSub.Location.Y, HmSub.Width, HmSub.Height), new Rectangle(HmMul.Location.X, HmMul.Location.Y, HmMul.Width, HmMul.Height), new Rectangle(HmDiv.Location.X, HmDiv.Location.Y, HmDiv.Width, HmDiv.Height) };
}
private void reziseChildControl()
{
Control[] controlP4 = new Control[] { panel4, qusNo, element1, element2, operation, line, nextQus, flp1, flp2, opt1, opt2, opt3, opt4, opt5, opt6, dopt1, dopt2, dopt3, dopt4, dopt5, dopt6, LaBackBt, LaFinishBt, results };
Control[] controlP2 = new Control[] { panel2, Easy, Hard, MdBackBt, eelem1, eelem2, eelem3, eelem4, eelem5, flp3, flp4, flp5, flp6 };
Control[] controlP1 = new Control[] { panel1, label1, listView3, HmAdd, HmSub, HmMul, HmDiv};
for (int j = 0; j < controlP4.Length; j++)
{
resizeControls(panel4Size[j], controlP4[j]);
}
for (int j = 0; j < controlP2.Length; j++)
{
resizeControls(panel2Size[j], controlP2[j]);
}
for (int j = 0; j < controlP1.Length; j++)
{
resizeControls(panel1Size[j], controlP1[j]);
}
}
private void Form1_Resize(object sender, EventArgs e)
{
reziseChildControl();
}
private void resizeControls(Rectangle originalContrl, Control control)
{
float xRatio = (float)(this.Width) / (float)(defaultSize.Width);
float yRatio = (float)(this.Height) / (float)(defaultSize.Height);
int newX = (int)(originalContrl.X * xRatio);
int newY = (int)(originalContrl.Y * yRatio);
int newWidth = (int)(originalContrl.Width * xRatio);
int newHeight = (int)(originalContrl.Height * yRatio);
control.Location = new Point(newX, newY);
control.Size = new Size(newWidth, newHeight);
}
}
Update: The NullReferenceException throwing because the Form1_Resize event occurs before Form1_Load event. Form1_Resize event shouldn't be called before i change the layout of window(by dragging or maximize the window size). But Resize event calling automatically at starting of the app before Form1 completely laading. On checking the Form1 property i could not find relevant property which could be the reason for calling resize event while starting. Tried selecting different values for the form1 layout properties, nothing much changes except WindowState propety. Even with different values for WindowState property the Resize event calling at starting.
its easy to see what value is going null with debugger that is the problem when you create your panelsize don't set whit any start value that going null, to
see these complete guide and examples for build metro style app
https://msdn.microsoft.com/en-us/library/windows/apps/br211380
hope that helps !!!
Added a simple condition statement to resizing code. It worked fine after that. But didn't able to figure it out exactly what caused calling form_resize event at starting. May be its add in in metro framework but not sure.
Thanks

C# How to put RadioButton inside Panel

I have searched everywhere, but the procedure are so painful. How to put multiple RadioButton into a panel programatically without using toolbox. I'm using WinForms. After several suggestion/s, I still can't add the radiobuttons inside the panel.
public partial class Form1 : Form
{
RadioButton[] RadioButton_WallFirstStorey_Yes = new RadioButton[100];
RadioButton[] RadioButton_WallFirstStorey_No = new RadioButton[100];
Panel[] Panel_WallFirstStorey = new Panel[100];
int CheckBoxWidth = 100;
public Form1()
{
InitializeComponent();
//code
//procedure
}
private void InitializeRadioButton_Wall(RadioButton RadioButtonX)
{
RadioButtonX.AutoSize = true;
RadioButtonX.Font = SystemFonts.DefaultFont;
RadioButtonX.BackColor = Color.Transparent;
Controls.Add(RadioButtonX);
}
private void InitializePanel_Wall(Panel PanelX)
{
PanelX.BackColor = Color.PaleTurquoise;
PanelX.BorderStyle = BorderStyle.Fixed3D;
PanelX.BringToFront();
Controls.Add(PanelX);
}
private void MyProcedure()
{
int i;
for (i = 1; i <= 100; i++)
{
Panel_WallFirstStorey[i] = new Panel();
InitializePanel_Wall(Panel_WallFirstStorey[i]);
Panel_WallFirstStorey[i].Location = new Point(Label_SeparatorLineVertical[ColumnMinimum + i].Location.X, Label_SeparatorLineHorizontal[RowMinimum + i].Location.Y);
Panel_WallFirstStorey[i].Width = (Label_SeparatorLineVertical[ColumnMaximum].Location.X - Label_SeparatorLineVertical[ColumnMinimum].Location.X) / (ColumnMaximum - ColumnMinimum);
Panel_WallFirstStorey[i].Height = CheckBoxWidth;
Panel_WallFirstStorey[i].SendToBack();
}
for (i = 1; i <= 100; i++)
{
RadioButton_WallFirstStorey_Yes[i] = new RadioButton();
RadioButton_WallFirstStorey_No[i] = new RadioButton();
Panel_WallFirstStorey[i].Controls.Add(RadioButton_WallFirstStorey_Yes[i]);//I add this stuff
Panel_WallFirstStorey[i].Controls.Add(RadioButton_WallFirstStorey_No[i]);//I add this stuff
InitializeRadioButton_Wall(RadioButton_WallFirstStorey_Yes[i]);
InitializeRadioButton_Wall(RadioButton_WallFirstStorey_No[i]);
RadioButton_WallFirstStorey_Yes[i].Text = "Yes";
RadioButton_WallFirstStorey_No[i].Text = "No";
RadioButton_WallFirstStorey_Yes[i].Location = new Point(Panel_WallFirstStorey[i].Width / 3, 0);
RadioButton_WallFirstStorey_No[i].Location = new Point(Panel_WallFirstStorey[i].Width * 2 / 3, 0);
RadioButton_WallFirstStorey_Yes[i].Font = SystemFonts.DefaultFont;
RadioButton_WallFirstStorey_No[i].Font = SystemFonts.DefaultFont;
RadioButton_WallFirstStorey_Yes[i].BringToFront();
RadioButton_WallFirstStorey_No[i].BringToFront();
}
}
}
Wow, your code is wrong in so many ways.... It creates controls over and over whenever a panel is painted, but it never really adds them anywere.
To add a radio button b to a panel p, it would be enough to do this:
RadioButton b = new RadioButton();
// Set properties for button here (text, location, handlers, etc.)
p.Controls.Add(b);
I'd try the following procedure instead of yours:
private void MyProcedure()
{
for (i = 1; i <= 100; i++)
{
RadioButton_WallFirstStorey_Yes[i] = new RadioButton();
RadioButton_WallFirstStorey_No[i] = new RadioButton();
InitializeRadioButton_Wall(RadioButton_WallFirstStorey_Yes[i]);
InitializeRadioButton_Wall(RadioButton_WallFirstStorey_No[i]);
RadioButton_WallFirstStorey_Yes[i].Text = "Yes";
RadioButton_WallFirstStorey_No[i].Text = "No";
RadioButton_WallFirstStorey_Yes[i].Location = new Point(Panel_WallFirstStorey[i].Location.X + Panel_WallFirstStorey[i].Width / 3, Panel_WallFirstStorey[i].Location.Y);
RadioButton_WallFirstStorey_No[i].Location = new Point(Panel_WallFirstStorey[i].Location.X + Panel_WallFirstStorey[i].Width * 2 / 3, Panel_WallFirstStorey[i].Location.Y);
Panel_WallFirstStorey[i].Controls.Add(RadioButton_WallFirstStorey_Yes[i]);
Panel_WallFirstStorey[i].Controls.Add(RadioButton_WallFirstStorey_No[i]);
}
}
The following code indicates you're still doing it wrong, adding the radio buttons to the form itself, but positioning them as if you had added them to the panel:
RadioButton_WallFirstStorey_Yes[i].Location = new Point(Panel_WallFirstStorey[i].Location.X + Panel_WallFirstStorey[i].Width / 3, Panel_WallFirstStorey[i].Location.Y);
If you added the button to the panel, it would most probably be invisible because it is outside the panel. If you added the button to the panel, you'd have to use coordinates relative to the panel's client area.
RadioButton_WallFirstStorey_Yes[i].Location = new Point(Panel_WallFirstStorey[i].Width / 3, 0);
RadioButton_WallFirstStorey_No[i].Location = new Point(Panel_WallFirstStorey[i].Width * 2 / 3, 0);
Your update code shows clearly where your error is:
private void InitializeRadioButton_Wall(RadioButton RadioButtonX)
{
RadioButtonX.AutoSize = true;
RadioButtonX.Font = SystemFonts.DefaultFont;
RadioButtonX.BackColor = Color.Transparent;
// REMOVE THIS LINE!!
Controls.Add(RadioButtonX);
}
The last line adds the radio button to the form. As we've been telling you all the time. Remove the line I marked above. Then, the radio buttons will be added to the panels only. After that it is a question of getting the positions right.
You can for example create a panel (or a GroupBox) and in a loop add the RadioButtons.
It should work like with any other control in Winforms.
// Adds 10 Radiobuttons with the name "Radio <number>"
public Form1()
{
InitializeComponent();
for (int n = 0; n < 10; n++)
{
// First instantiate a new RadioButton.
RadioButton button = new RadioButton();
// Now the name of the button.
button.Text = "Radio" + n;
// Dock the button to the top of the GroupBox (to put them in order)
button.Dock = DockStyle.Top;
// Add the button to the GroupBox.
this.groupBoxRadio.Controls.Add(button);
}
}
Your question is not very clear, and no code for context, but you should be able to create an instance of a new radiobutton and add it to the controls of the panel.
It may also be best to use RadioButtonList like Harvey has mentioned, but to try to answer your question:
var someRadioBtn = new RadioButton();
// set properties...
pnlMyPanel.Controls.Add(someRadioBtn);

Adding dynamic controls to winform not working

I am creating dynamic PictureBox and label in WinForms. For this I have created a method which creates these items on the basis of given integer. In the first run while loading the form, its works smoothly, but when I pass any integer from a dropdown box, it does not make any changes. I tried debugging the code, and all the labels are created accordingly but it is not reflected in the winForm. I tried using Invalidate, Update, Refresh but non of them worked.
Here is the method that I have implemented.
private void createPictureBox(int size)
{
//this.Controls.Clear();
panel1.Controls.Clear();
Label[] ParameterLabel = new Label[size];
PictureBox[] ParameterBack = new PictureBox[size];
int y_value = 11;
this.Refresh();
for (int i = 0; i < size; ++i)
{
ParameterLabel[i] = new Label();
ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Font = new System.Drawing.Font("Calibri", 8, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
ParameterLabel[i].ForeColor = System.Drawing.Color.White;
ParameterLabel[i].BackColor = System.Drawing.Color.FromArgb(1, 0, 64);
ParameterLabel[i].Size = new System.Drawing.Size(145, 20);
ParameterLabel[i].Location = new Point(30, y_value);
ParameterLabel[i].Anchor = AnchorStyles.Left;
ParameterLabel[i].Visible = true;
ParameterBack[i] = new PictureBox();
ParameterBack[i].Image = Image.FromFile(STR_SETTING_PATH + "\\" + STR_IDEA_NO_XXXXX + "_01_nv.png");
ParameterBack[i].Size = new System.Drawing.Size(400, 32);
ParameterBack[i].Location = new Point(2, y_value - 10);
ParameterBack[i].Anchor = AnchorStyles.Left;
ParameterBack[i].Visible = true;
//this.Controls.Add(ParameterBack[i]);
y_value += 37;
}
panel1.Controls.AddRange(ParameterLabel);
panel1.Controls.AddRange(ParameterBack);
panel1.Invalidate();
}
Who can you distinguish between controls created in the first call and those created in other calls? I've tested your function with a tiny change, it seems to be working fine:
int CallIndex = 0; // this is on the form level
private void button1_Click(object sender, EventArgs e)
{
createPictureBox(3);
CallIndex += 1;
}
private void createPictureBox(int size)
{
// this has the exact same code as your method (copy-paste into my visual studio),
// except this change:
// ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Text = string.Format("Test {0}", CallIndex); // instead of the row above
}
I did remove the previously added controls and added the new one after which apparently solved my problem. The problem was due to piling of Controls one over another. I first removed the previously created controls using
this.Controls.Remove(UserControl1);
Then re-created its instance, which solved my problem.

Dynamic creation of control

for (int i = 0; i < 200; i++)
{
Control control = new Control();
control = new CheckBox();
Size size = control.Size;
Point point = new Point(20, 22);
control.Location = point;
int width = size.Width + 5;
i += width;
list.Add(control);
}
foreach(Control c in list)
{
}
how do I create a new instance of checkbox? Because this way I am getting just one checkbox each time. I want to get three checkbox in each row.
Is this winforms? A first point: you don't need the new Control() each time (you simly discard it anyway when you new CheckBox(). How exactly do you want the layout to appear? Can you describe it a bit more please?
I imagine TableLayoutPanel might be a reasonable start...
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Form form = new Form();
TableLayoutPanel layout = new TableLayoutPanel();
layout.Dock = DockStyle.Fill;
form.Controls.Add(layout);
layout.AutoScroll = true;
layout.ColumnCount = 3;
// size the columns (choice just to show options, not to be pretty)
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 200));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50));
layout.ColumnStyles.Add(new ColumnStyle(SizeType.AutoSize));
layout.GrowStyle = TableLayoutPanelGrowStyle.AddRows;
for (int i = 0; i < 200; i++)
{
CheckBox chk = new CheckBox();
chk.Text = "item " + i;
layout.Controls.Add(chk);
}
Application.Run(form);
}
Otherwise, you'll need to manually set the Location (or Top and Left) of each; not simple.
Your code has problems. Let's work from sample code rather than a lesson. I'll create a Panel first, nice if you want to remove the checkboxes you created. You'd probably be interested in the user clicking a checkbox so lets add an event for that. Start a new WF project and drop a button on the form. Double click it, then paste this code:
private void button1_Click(object sender, EventArgs e) {
// Give the 3 checkboxes a decent spacing
int height = this.Font.Height * 3 / 2;
// Create the panel first, add it to the form
Panel pnl = new Panel();
pnl.Size = new Size(100, 3 * height);
pnl.Location = new Point(10, 5);
this.Controls.Add(pnl);
// Make three checkboxes now
for (int ix = 0; ix < 3; ++ix) {
CheckBox box = new CheckBox();
box.Size = new Size(100, height);
// As pointed out, avoid overlapping them
box.Location = new Point(0, ix * height);
box.Text = "Option #" + (ix + 1).ToString();
box.Tag = ix;
// We want to know when the user checked it
box.CheckedChanged += new EventHandler(box_CheckedChanged);
// The panel is the container
pnl.Controls.Add(box);
}
}
void box_CheckedChanged(object sender, EventArgs e) {
// "sender" tells you which checkbox was checked
CheckBox box = sender as CheckBox;
// I used the Tag property to store contextual info, just the index here
int index = (int)box.Tag;
// Do something more interesting here...
if (box.Checked) {
MessageBox.Show(string.Format("You checked option #{0}", index + 1));
}
}
It looks like you get your 200 instances, all placed at the same point.
Instantiate 3 new checkboxes inside your loop body, set their properties accordingly and add each of them to the list. After the code above is complete, you will have 600 checkboxes.
list.Add(Control1);
list.Add(Control2);
list.Add(Control3);
I am not sure about what you are trying to do, but I cleaned up your code a bit:
for (int i = 0; i < 200; i++)
{
Control control = new CheckBox();
control.Location = new Point(20, 22);
i += control.Size.Width + 5;
list.Add(control);
}
You should not add a new instance to the list if you want to add the control you just made.
Also:
Control control = new Control();
control = new CheckBox();
Is a bit redundant. Also to not get one control at the same spot multiple times you should alter the point. Hope this helps

Categories