This code adds new buttons depending on the # of items saved on my items table.
mySQL WorkBench
I dont know why it keeps on duplicating my buttons. I just want to keep the buttons arranged into 4 columns.
object[] itemDetail;
object[] itemLi = itemsWS.searchItem("", "drinks", "all");
int cleft = 0;
for (int i = 0; i < itemLi.Length; i++)
{
itemDetail = itemsWS.getItemInfo(itemLi[i].ToString());
for (int x = 35; x < 537; x++)
{
Button myButton = new Button();
myButton.Text = itemDetail[0].ToString();
myButton.Top = cleft * 80;
myButton.Left = 70;
myButton.Location = new Point(x, cleft);
myButton.Size = new Size(100, 60);
tabPage1.Controls.Add(myButton);
cleft = cleft + 15;
//cleft = cleft + 1;
x += 134;
}
}
try something like this:
int x = 35;
int cleft = 0;
foreach (var item in itemLi)
{
Button myButton = new Button();
myButton.Text = itemDetail[0].ToString();
myButton.Top = cleft * 80;
myButton.Left = 70;
myButton.Location = new Point(x, cleft);
myButton.Size = new Size(100, 60);
tabPage1.Controls.Add(myButton);
x += 134;
// Check if x is greater than form size,
// If so, resets x, and increments cleft
if (x >= 537)
{
x == 35;
cleft += 15
}
}
I'm not exactly sure what x and cleft are doing, but you get the idea (hopefully)
You can also put FlowLayoutPanel inside the Bread tabpage, then just set the Orientation property of the FlowLayoutPanel, then do Ben's suggestion without the Top, Left, Location, cleft, and x stuff so you won't need to set the location of the Buttons.
Related
For a School assignment we are making a Chess game in C#, in which we have to learn to work in a Object-Oriented way. The board is made out of a 2D picturebox array in a nested for loop
//Create the Board Pattern out of PictureBoxes
#region Checkerboard
PictureBox[,] Vak = new PictureBox[8, 8];
for (int i = 0; i < 8; i++)
{
for (int x = 0; x < 8; x++)
{
Vak[i, x] = new PictureBox();
Vak[i, x].Name = String.Format("{0},{1}", i, x);
Vak[i, x].Width = 50;
Vak[i, x].Height = 50;
Vak[i, x].Location = new Point(xpos, ypos);
Vak[i, x].SizeMode = PictureBoxSizeMode.Zoom;
Vak[i, x].Click += Chess_Click;
if ((i + x) % 2 == 0)
{
Vak[i, x].BackColor = ColorTranslator.FromHtml("#e5e5e5"); //white ColorTranslator.FromHtml("#e5e5e5");
}
else
{
Vak[i, x].BackColor = ColorTranslator.FromHtml("#545454"); //black ColorTranslator.FromHtml("#545454");
}
xpos += 50;
this.Controls.Add(Vak[i, x]);
}
xpos = 50;
ypos += 50;
this.Controls.Add(border);
}
#endregion
On other posts i have found that i can Refer to a class (via the picturebox) using the .Tag property like so:
Vak[i,x].Tag = new Tower();
However, i cannot figure out a way to call properties from the Tower class from withing the tag
Say the Tower class has a property "name", how would i go about calling that
string objectname = Vak[i,x].Tag.(name?)
Sorry If this is a stupid question, but i am very new to programming.
Thanks!
You have to cast it, since Tag is an Object type:
Tower tower = Vak[i,x].Tag as Tower;
if(tower!=null)
{
//do stuff
}
However, i would avoid storing data structures in Tag properties like this.
i have an unknown amount of images that im adding to a Grid control with code and im kind of lost in the logic as images are inserted in wrong order. Have a look (Modulus like this because of testing):
grid.Height = this.Height;
grid.Width = this.Width;
grid.ShowGridLines = true;
for (int i = 0; i < 50; i++)
{
RowDefinition rowDef = new RowDefinition();
rowDef.Height = new GridLength(50);
grid.RowDefinitions.Add(rowDef);
ColumnDefinition colDef = new ColumnDefinition();
colDef.Width = new GridLength(50);
grid.ColumnDefinitions.Add(colDef);
}
int x = 1;
int y = 1;
for (int i = 0; i < 50; i++)
{
y++;
if (i % 10 == 0)
{
x++;
y = 1;
}
Image img = new Image() { Source = new BitmapImage(new Uri("Images/positive.png",UriKind.Relative)), Width = 50, Height = 50, Margin = new Thickness(2,2,2,2) };
grid.Children.Add(img);
Grid.SetRow(img, x);
Grid.SetColumn(img, y);
}
Result:
As you can see the images are starting on a new row every 10 image as the modulus says, but they do not start at the first row in the first coloumn.
What i want to achieve is this:
What am i doing wrong? Thanks!
Set intitial values as follows should solve your problem.
int x = -1;
int y = -1;
And inside if you should try
if (i % 10 == 0)
{
x++;
y = 0;
}
On your first iteration through the loop, i is 0.
(0 % 10 == 0) // true
So x is incremented by 1 immediately.
Set a breakpoint at the start of your for loop and follow the execution. In this case you'd have seen it immediately.
I'm trying to place a grid of labels on my winforms app. First, I'm populating a list of label objects of size (200 x 50) and then trying to place them so that when x reaches the width of the form (581), I increment y by 50 + 1
Here is my code:
private List<Label> _labels;
private int xOffset = 10;
private int yOffset = 10;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for(var i = 0; i <= 20; i++)
_labels.Add(new Label() { Name = "lbl" + i, Height = 50, Width = 200, MinimumSize = new Size(200, 50), BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D, Text = "Label "+i});
// 581, 517
var x = 0;
var y = 0;
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
lbl.Location = new Point(x, y);
}
this.Controls.Add(lbl);
x += x + lbl.Width;
}
}
It's only placing the even labels from the list on new lines. I'm not sure what I'm doing wrong.
I'm trying to place all of the labels in a grid like design. When one row is full, go to the next row and continue placing labels from the list on that new "row"
You need to move the Location setting code out of the resetting loop:
foreach (var lbl in _labels)
{
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
}
The problematic part is here
x += x + lbl.Width; //+= x
change it to
x += lbl.Width;
Get the
lbl.Location = new Point(x, y);
out of the if statement
if (x >= 580)
{
x = 0;
y = y + lbl.Height + 2;
//lbl.Location = new Point(x, y);
}
lbl.Location = new Point(x, y);
this.Controls.Add(lbl);
x += lbl.Width;
Try this using a Docked FlowLayoutPanel:
public partial class Form1 : Form
{
List<Label> labels;
public Form1()
{
InitializeComponent();
this.labels=new List<Label>();
AddLabelsToFrom(20);
}
void AddLabelsToFrom(int count)
{
for (int i=0; i<count; i++)
{
var lbl=new Label() { Name="lbl"+i, Height=50, Width=200, MinimumSize=new Size(200, 50), BorderStyle=System.Windows.Forms.BorderStyle.Fixed3D, Text="Label "+i };
labels.Add(lbl);
flowLayoutPanel1.Controls.Add(lbl);
}
}
}
void SetGridLabel()
{
for (int i = 0; ; i++)
{
for (int j = 0; ; j++)
{
Label L = new Label();
L.TextAlign = ContentAlignment.MiddleCenter;
L.AutoSize = false;
L.Size = new Size(70, 70);
L.Text = "Test_" + j + "_" + i;
L.Location = new Point(j * L.Size.Width, i * L.Size.Height);
if ((i + 1) * L.Size.Height > this.Size.Height)
return;
if ((j + 1) * L.Size.Width > this.Size.Width)
break;
this.Controls.Add(L);
}
}
}
private List<Label> _labels;
public Form1()
{
InitializeComponent();
_labels = new List<Label>();
for (var i = 0; i <= 20; i++)
_labels.Add(new Label()
{
Name = "lbl" + i, Height = 50,Width = 200,
Size = MinimumSize = new Size(200, 50),
Location = new Point(i * 200 % 600, 50 * (i * 200 / 600)),
BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D,
Text = "Label " + i
});
foreach (var lbl in _labels) this.Controls.Add(lbl);
}
I'm using vs2012 (C#) for my app and I'm looking for a way to add a label and textbox to a tabPage on my form, dynamically. But because the # of controls to be added could be larger than 10, I am also trying to add them in "columns" so the container control will only scroll horizontally, not vertically.
For instance, I'm trying to do something like this:
LabelControl LabelControl LabelControl LabelControl
TextboxControl TextboxControl TextboxControl TextboxControl
LabelControl LabelControl LabelControl LabelControl
TextboxControl TextboxControl TextboxControl TextboxControl
etc.
The "container" control is a TabPage, so I know I have to grab the height from that and use it. I am able to get the textboxes to render but am having difficulty with the label controls being on top, then the textboxes below.
Here's what I've got so far:
int height = tabPageBicycle.Height;
Point startLocation = new Point(0, 0);
int previousX = 0;
int previousY = 0;
int currentX = 0;
for (int x = 0; x < 75; x++)
{
Label label = new Label();
TextEdit text = new TextEdit();
label.Text = x.ToString();
text.Text = x.ToString();
label.Location = new Point(currentX, previousY);
tabPageBicycle.Controls.Add(label);
if ((height - previousY) < text.Height)
{
currentX += 100;
previousY = 0;
}
text.Location = new Point(currentX + text.Height + 5, previousY + 50);
previousX = text.Location.X;
previousY = text.Location.Y;
tabPageBicycle.Controls.Add(text);
}
Any clues as to what I am doing wrong?
Ended up figuring it out, after taking it line-by-line and seeing what was being done in the loop. Here's the final code I used....as always, I'm open to suggestions/comments/etc. on how to make it better/more efficient.
int labelY = 0;
int textY = 0;
int startX = 5;
int startY = 5;
int height = tabPageBicycle.Height;
Point startLocation = new Point(0, 0);
for (int x = 0; x < 75; x++)
{
Label label = new Label();
TextEdit text = new TextEdit();
label.AutoSize = true;
label.Text = x.ToString();
text.Text = x.ToString();
//Determine if the next set of controls will be past the height of the container.
//If so, start on the next column (change X).
if ((height - textY) < ((label.Height + 10) + text.Height))
{
startX += 125;
labelY = 0;
}
//Start of new column.
if (labelY == 0)
label.Location = new Point(startX, startY);
else
label.Location = new Point(startX, textY + label.Height + 10);
tabPageBicycle.Controls.Add(label);
labelY = label.Location.Y;
textY = labelY + 15;
text.Location = new Point(startX, textY);
textY = text.Location.Y;
tabPageBicycle.Controls.Add(text);
}
and the results:
I hope it helps someone else out!
I'm trying to create 81 picture boxes and have them automatically positioned a certain distance apart from one another but they don't seem to be placing in any logical order. I have to initialize the X point to -1700 for them to even appear on the screen. The following code gets the first 15 where I want them but then they start stacking on top of one another instead of continuing the pattern. This is the result of about an hour of tinkering but initially the logic looked fine. I even had a message box that would display the current X,Y that was being set and it was correct it just would not place them at those coordinates.
int X = -1700;
int Y = 0;
for (int i = 0; i < 81; i++)
{
this.Controls.Add(championThumbNailsArray[i]);
championThumbNailsArray[i].Height = 80;
championThumbNailsArray[i].Width = 80;
championThumbNailsArray[i].Location = new Point(X, Y);
// MessageBox.Show(Convert.ToString(X) + "," + Convert.ToString(Y));
championThumbNailsArray[i].ImageLocation = akali.grabPicture();
//championThumbNailsArray[i].ImageLocation = championsArray[i].grabPicture();
if (X <= 425)
X = X + 85;
else
{
X = -1700;
Y = Y + 85;
}
}
Instead of manually placing elements use a FlowLayoutPanel. Add the controls to the panel and let it do the arrangement for you.
This code works as you are expecting
private void Form1_Load(object sender, EventArgs e)
{
int x = 0;
int y = 0;
for (int i = 0; i < 81; i++)
{
PictureBox p = new PictureBox();
p.BorderStyle = BorderStyle.Fixed3D;
p.Height = 80;
p.Width = 80;
p.Location = new Point(x, y);
x += 85;
if (x > 425)
{
x = 0;
y += 85;
}
this.Controls.Add(p);
}
}
But I would go with something like #Ed said, a FlowLayout control