I have a tableLayoutPanel (size of 10x10 columns & rows added from the toolbox) and I have added single Panel into every cells so I could add two objects/components into a cell. Every cell contains a label and a button. The problem is I couldn't add the two components into a panel programatically. What should I do?
Here is my code:
private int[,] grid;
private Button[,] btn_grid;
private Label[,] lbl_grid;
private int timer = 0;
private Panel[,] pnl_grid;
private bool createGrid()
{
Random rnd1 = new Random();
grid = new int[width, height];
pnl_grid = new Panel[width, height];
btn_grid = new Button[width, height];
lbl_grid = new Label[width, height];
for (int x = 0; x <width; x++)
{
for (int y = 0; y < height; y++)
{
btn_grid[x, y] = createButton(x, y);
lbl_grid[x, y] = createLables(x,y);
pnl_grid[x, y] = createPanels(x, y);
**//something's missing here to add the 2 components into a panel**
tableLayoutPanel2.Controls.Add(pnl_grid[x,y]);
}
}}
private Button createButton(int gridX, int gridY)
{
Button bttn = new Button();
bttn.Text = "";
bttn.Name = gridX.ToString() + " " + gridY.ToString();
bttn.Size = new System.Drawing.Size(30, 30);
Controls.AddRange(new System.Windows.Forms.Control[] { bttn, });
bttn.Click += new System.EventHandler(bttnOnclick);
//bttn.MouseClick += new System.Windows.Forms.MouseEventHandler(this.bttnOnRightClick);
return bttn;
}
private Label createLables(int gridX, int gridY)
{
Label lbl = new Label();
lbl.Name = gridX.ToString() + " " + gridY.ToString();
lbl.Text = "0";
lbl.Size = new System.Drawing.Size(30, 30);
//lbl.Font = new Font("Microsoft Sans Serif", 15.75f, lbl.Font.Style, lbl.Font.Unit);
Controls.AddRange(new System.Windows.Forms.Control[] { lbl, });
return lbl;
}
private Panel createPanels(int gridX, int gridY)
{
Panel pnl = new Panel();
pnl.Name = gridX.ToString() + " " + gridY.ToString();
//pnl.Text = "0";
pnl.Size = new System.Drawing.Size(30, 30);
//lbl.Font = new Font("Microsoft Sans Serif", 15.75f, lbl.Font.Style, lbl.Font.Unit);
Controls.AddRange(new System.Windows.Forms.Control[] { pnl, });
return pnl;
}
Thank you for your appreciated attention and help!
Your code is fine until the last moment when you have to add the controls to the tableLayourPanel or to the panel. You just add the panel but not the button/label to the panel.
Thus, you have to options:
Adding button and label to the panel and the panel to the tableLayoutPanel (which seems the most logical one):
btn_grid[x, y] = createButton(x, y);
lbl_grid[x, y] = createLables(x,y);
pnl_grid[x, y] = createPanels(x, y);
pnl_grid[x, y].Controls.Add(btn_grid[x, y]);
pnl_grid[x, y].Controls.Add(lbl_grid[x, y]);
tableLayoutPanel2.Controls.Add(pnl_grid[x,y]);
or adding the three elements directly to the tableLayoutPanel:
btn_grid[x, y] = createButton(x, y);
lbl_grid[x, y] = createLables(x,y);
pnl_grid[x, y] = createPanels(x, y);
tableLayoutPanel2.Controls.Add(btn_grid[x,y]);
tableLayoutPanel2.Controls.Add(lbl_grid[x,y]);
tableLayoutPanel2.Controls.Add(pnl_grid[x,y]);
You can remove the Controls.AddRange call from createLables, createButton createPanels method.
Then you can modify your createpanels method as below
private Panel createPanels(int gridX, int gridY)
{
Label lbl = lbl_grid[gridX,gridY];
Button btn = btn_grid[gridX,gridY];
Panel pnl = new Panel();
pnl.Name = gridX.ToString() + " " + gridY.ToString();
//pnl.Text = "0";
pnl.Size = new System.Drawing.Size(30, 30);
//lbl.Font = new Font("Microsoft Sans Serif", 15.75f, lbl.Font.Style, lbl.Font.Unit);
pnl.Controls.AddRange(new System.Windows.Forms.Control[] { lbl,btn });
lbl.Dock = DockStyle.Top;
btn.Dock = DockStyle.Fill;
return pnl;
}
Hope this helps
Related
So I'm creating some panels with the following code
private void button1_Click(object sender, EventArgs e)
{
int xlocation = 5;
for (int i = 0; i < 10; i++)
{
Panel panel = new Panel();
{
panel.Name = string.Format("{0}", i);
panel.Text = string.Format(i.ToString());
panel.BackColor = Color.White;
panel.Location = new System.Drawing.Point(xlocation, 30);
panel.Width = flowLayoutPanel1.Width;
panel.Height = 50;
panel.MouseEnter += new System.EventHandler(this.panel_MouseEnter);
flowLayoutPanel1.Controls.Add(panel);
Label label = new Label();
label.Location = new System.Drawing.Point(15, 10);
label.AutoSize = true;
label.Font = new System.Drawing.Font("Calibri", 13F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
label.ForeColor = System.Drawing.Color.FromArgb(64, 64, 64);
label.Text = string.Format("{0}", "GNU" + i);
panel.Controls.Add(label);
Label label10 = new Label();
label10.Location = new System.Drawing.Point(15, 35);
label10.AutoSize = true;
label10.Font = new System.Drawing.Font("Calibri", 8F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
label10.ForeColor = System.Drawing.Color.FromArgb(64, 64, 64);
label10.Text = string.Format("{0}", "hest");
panel.Controls.Add(label10);
}
xlocation = xlocation + 85;
}
}
The problem is when I resize my form, my flowLayoutPanel obviously gets bigger, but the panels inside doesn't.
I have tried using the
private void Form1_Resize(object sender, EventArgs e)
{
}
But it doesn't seem to work.
Any answer is much appreciated!
Thanks!
You can either use the Anchor property and set it to Right and Left, or can dock each panel to parent control. Something like this should work:
Panel panel = new Panel();
panel.Dock = DockStyle.Top; // Docks the panel to top, and fills to the width of Parent control
panel.Anchor = (AnchorStyles.Right | AnchorStyles.Left); // Set anchor to right and left
I found a solution. I just created a list with my panels like so
List<Panel> pnls = new List<Panel>();
And just did like so to make them follow the width of my flowlayoutpanel, so you can actually use a flowlayoutpanel ;-)
private void Kontrol_Resize(object sender, EventArgs e)
{
for (int i = 0; i < pnls.Count; i++)
{
pnls[i].Width = activityData.Width - 24;
pnls[i].Height = activityData.Height / 4;
}
}
Why not lable_2 and lable_3 are not displayed?
private void button2_Click(object sender, EventArgs e)
{
int X = 153;
int Y = 34;
for (int i = 1; i < 4; i++)
{
Panel pnl = new Panel();
pnl.SuspendLayout();
pnl.Location = new Point(X, Y);
pnl.Name = "pnl"+i;
pnl.Size = new Size(200, 57);
pnl.BorderStyle = BorderStyle.FixedSingle;
Label lbl = new Label();
lbl.Location = new Point(X - 100, Y - 17);
lbl.Name = "lbl" + i;
lbl.Size = new Size(75, 23);
lbl.Text = "lable_" +i;
pnl.Controls.Add(lbl);
pnl.ResumeLayout(false);
this.Controls.Add(pnl);
Y = Y + 95;
}
}
The Y-position of the 2nd and 3rd labels is outside the bounds of the panel. Instead of giving the location, you can use the Dock property of the Label.
Label lbl = new Label();
lbl.Text = "Label test";
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.Dock = DockStyle.Fill;
panel1.Controls.Add(lbl);
This code of my button:
int offsetY = 5;
int x = 0;
int y = 0;
int index = 1;
//Start adds new panel and new label
Panel b = new Panel();
Label la = new Label();
//Adds panel properties
b.Controls.Add(la);
b.Location = new Point(x, y + offsetY);
b.Size = new Size(633, 119);
newhaven.Class1 cl = new newhaven.Class1();
b.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
flowLayoutPanel1.Controls.Add(b);
b.ResumeLayout(false);
//Adds label properties
x = 0;
y = -20;
la.Location = new Point(x,y);
// la.Size = new Size(60, 30);
la.Text = "Hello";
flowLayoutPanel1.Controls.Add(la);
I want to hello to be in the panel)
Are can you help me?
You almost got it right, but need to take care of the position co-ordinates for the label, please ensure that they lie inside the panel co-ordinates.
The following works:
int offsetY = 5;
int x = 0;
int y = 0;
int index = 1;
//Start adds new panel and new label
Panel b = new Panel();
Label la = new Label();
//Adds panel properties
b.Controls.Add(la);
b.Location = new Point(x, y + offsetY);
b.Size = new Size(633, 119);
//newhaven.Class1 cl = new newhaven.Class1();
b.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
flowLayoutPanel1.Controls.Add(b);
b.ResumeLayout(false);
// Adds label properties -
// commented the co-ordinates and using the same as that of panel
//x = 0;
//y = -20;
la.Location = new Point(x, y + offsetY);
// la.Size = new Size(60, 30);
la.Text = "Hello";
// no need to add the label separately, its inside the panel
//flowLayoutPanel1.Controls.Add(la);
I have multiple GroupBox's, and that's why I set AutoScroll to true. I create all controls in Form_Load. How to place one button after all GroupBox'es?
The code, where I create GroupBoxes:
for (int i = 0; i < 10; i++)
{
GroupBox gb = new GroupBox();
gb.Name = "GroupBox" + (i + 1);
gb.Size = new Size(500, 200);
gb.Location = new Point(40, loc);
gb.BackColor = System.Drawing.Color.Aquamarine;
Label q_text = new Label(); // текст питання
q_text.Name = "label" + (i + 1);
q_text.Text = "Питання" + (i + 1);
q_text.Font = new Font("Aria", 10, FontStyle.Bold);
q_text.Location = new Point(10, 10);
gb.Controls.Add(q_text);
int iter = q_text.Location.Y + 30;
if (i <= 5)
{
foreach (string key in questions[i].answers.Keys)
{
RadioButton rb = new RadioButton();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}else
if (i > 5)
{
foreach (string key in questions[i].answers.Keys)
{
CheckBox rb = new CheckBox();
rb.Text = key;
rb.Size = new Size(120, 25);
rb.Location = new Point(q_text.Location.X + 10, iter);
iter += 30;
gb.Controls.Add(rb);
}
}
this.Controls.Add(gb);
loc += 200;
Place all the scrollable group boxes in one panel which is set to AutoScroll = true. Below this panel is another one containing the fixed button. This panel is docked to the bottom.
Since you are using a loc variable, you can do:
btnMyButton.Locaction= new Point(40, loc);
Anyway, if you want to find the position of the last group box dynamically, try this:
double leftPos=0,topPos=0;
foreach(Control c in Forms.Controls)
{
if(c.Name=="GroupBox")
{
if(c.Left>leftPos)
leftPos=c.Left;
if(c.Top>topPos)
topPos=c.Top;
}
}
I'm trying to making dynamic controls (labels, pictureboxes and buttons) by making controls in a foreach. The foreach is controlled by datarows, which are created from an SQL function that I call for.
The problem is that my graphics don't seem to work on my pictureboxes as it is now.
So far I've got this as code:
Global variables:
private int i = 0, beginningHeight = 70, addingToHeight = 55;
PictureBox picturebox = new PictureBox();
The functions:
private void tonenAlleCategorieen()
{
foreach (DataRow dr in blCategorie.getAlleCategorieenMetLimieten())
{
//making labels dyanmic and fill them with the correct text (from database)
string categorie = (string)dr.Field<string>("Omschrijving");
Label label = new Label();
label.BackColor = Color.Transparent;
label.ForeColor = Color.FromArgb(97, 97, 97);
label.Font = new Font("Myriam Pro", 10, FontStyle.Bold);
label.Width = 200;
label.Name = categorie;
label.Text = categorie;
label.BackColor = Color.Transparent;
label.Location = new Point(30, beginningHeight + addingToHeight);
this.Controls.Add(label);
// getting the figures (max figures) from the db to show in a label
double limiet = (double)dr.Field<double>("maximumBedrag");
Label labeltest = new Label();
labeltest.BackColor = Color.Transparent;
labeltest.ForeColor = Color.FromArgb(97, 97, 97);
labeltest.Font = new Font("Myriam Pro", 8, FontStyle.Bold);
labeltest.Width = 200;
labeltest.Name = Convert.ToString(limiet);
labeltest.Text = "Limiet: " + Convert.ToString(limiet) + "€";
labeltest.BackColor = Color.Transparent;
labeltest.Location = new Point(30, (beginningHeight + 27) + addingToHeight);
this.Controls.Add(labeltest);
//making pictureboxes for every single row in the db
PictureBox picturebox = new PictureBox();
picturebox.Width = 400;
picturebox.Name = "picturebox" + i;
picturebox.Height = 15;
picturebox.Location = new Point(30, (beginningHeight + 27) + addingToHeight);
this.Controls.Add(picturebox);
//calling the paint event for drawing inside the pictureboxes
picturebox.Paint += new PaintEventHandler(picturebox_Paint);
//adjusting height (55px extra per new row)
beginningHeight += 55;
i++;
}
}
private void picturebox_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
//draw here
//Graphics g = picturebox.CreateGraphics();
int x = 30;
int y = (beginningHeight + 27) + addingToHeight;
int breedteGebruikt = 200;
int breedteNietGebruikt = picturebox.Width - breedteGebruikt;
int hoogteBalk = picturebox.Height;
g.DrawRectangle(new Pen(Color.Red), new Rectangle(10, 5, 50, 5));
g.FillRectangle(Brushes.Green, x, y, breedteNietGebruikt, hoogteBalk);
g.FillRectangle(Brushes.Red, x, y, breedteGebruikt, hoogteBalk);
picturebox.Refresh();
}
Can anybody help me out here and tell me how I can add the graphics into my pictureboxes so I can see how much percentage of my picturebox should be filled?
Here is a picture example to have a good look onto it:
As you see in the above image it currently doesn't work, and I've put data in the database for the first record named "Boodschappen" which should now be filled in by my graphics for 30% in this example.
Does anybody know a solution please? :)
Thanks
Now the troubles only rise on this part: I'm not allowed to add the g
to this.Controls.Add(g); it gives me the error Argument 1: cannot
convert from 'System.Drawing.Graphics' to
'System.Windows.Forms.Control
It's clear you can't add Graphics as a control. Also if you draw that way your drawing will disappear when picturebox or form repainted. So you should draw inside the Paint event of picturebox.
double maxLimit = 0;
int maxleftpos = 0;
private void tonenAlleCategorieen()
{
foreach (DataRow dr in blCategorie.getAlleCategorieenMetLimieten())
{
//making labels dyanmic and fill them with the correct text (from database)
string categorie = (string)dr.Field<string>("Omschrijving");
Label label = new Label();
label.BackColor = Color.Transparent;
label.ForeColor = Color.FromArgb(97, 97, 97);
label.Font = new Font("Myriam Pro", 10, FontStyle.Bold);
label.Width = 200;
label.Name = categorie;
label.Text = categorie;
label.BackColor = Color.Transparent;
label.Location = new Point(10, beginningHeight + addingToHeight);
maxleftpos = Math.Max(label.Left + label.Width, maxleftpos);
this.Controls.Add(label);
// getting the figures (max figures) from the db to show in a label
double limiet = (double)dr.Field<double>("maximumBedrag");
maxLimit = Math.Max(limiet, maxLimit);
Label labeltest = new Label();
labeltest.BackColor = Color.Transparent;
labeltest.ForeColor = Color.FromArgb(97, 97, 97);
labeltest.Font = new Font("Myriam Pro", 8, FontStyle.Bold);
labeltest.Width = 200;
labeltest.Name = Convert.ToString(limiet);
labeltest.Text = "Limiet: " + Convert.ToString(limiet) + "€";
labeltest.BackColor = Color.Transparent;
labeltest.Location = new Point(30, (beginningHeight + 27) + addingToHeight);
this.Controls.Add(labeltest);
//making pictureboxes for every single row in the db
PictureBox picturebox = new PictureBox();
picturebox.Width = 200;
picturebox.Name = "picturebox" + i;
picturebox.Height = 15;
picturebox.Tag = limiet;
picturebox.Location = new Point(100, (beginningHeight + 27) + addingToHeight);
this.Controls.Add(picturebox);
picturebox.BringToFront();
//calling the paint event for drawing inside the pictureboxes
picturebox.Paint += new PaintEventHandler(picturebox_Paint);
//adjusting height (55px extra per new row)
beginningHeight += 55;
i++;
}
foreach (Control c in this.Controls)
{
if (c is PictureBox)
{
c.Location = new Point(maxleftpos, c.Top);
}
}
if (this.Width<maxleftpos+150)
{
this.Width = maxleftpos + 50;
}
this.Refresh();
}
private void picturebox_Paint(object sender, PaintEventArgs e)
{
PictureBox p = sender as PictureBox;
Graphics gr = e.Graphics;
gr.ResetTransform();
//Graphics g = picturebox.CreateGraphics();
int breedteGebruikt = Convert.ToInt32((double)p.Tag);
int max = Convert.ToInt32(maxLimit);
int grwidht = breedteGebruikt * p.Width / max;
gr.DrawRectangle(new Pen(Color.Red), new Rectangle(10, 5, 50, 5));
gr.FillRectangle(Brushes.Green, 0, 0, p.Width, p.Height);
gr.FillRectangle(Brushes.Red, 0, 0, grwidht, p.Height);
}