how to position an object using variables - c#

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

Related

Evenly spaced grid that allows drag/drop

I need to create a WinForm application that allows the user to drag from a set of images, and position them on a grid, a tile designer of sorts.
I've tried using the TableLayoutPanel, however It seems to get rather slow when you have a grid 100x100, I was just wondering if there are any alternative methods out there that would allow the user to drag a tile onto the grid layout, and expand the size of the grid if they required.
Thank you.
If tiles are contiguous, you can get the first "empty cell"
private readonly Size tileSize = new Size(200, 200);
private void button1_Click(object sender, EventArgs e)
{
var pb = new PictureBox();
var pt = GetEmptyCell(tileSize);
pb.Location = pt;
pb.Size = tileSize;
Controls.Add(pb);
}
private Point GetEmptyCell(Size TileSize)
{
var ctrl = GetChildAtPoint(new Point(0, 0));
if (ctrl == null && TileSize.Width < Width && TileSize.Height < Height)
return new Point(0, 0);
for (int x = 0; x < Width; x++)
{
for (int y = 0; y < Height; y++)
{
ctrl = GetChildAtPoint(new Point(x, y));
if (ctrl == null && x + TileSize.Width < Width && y + TileSize.Height < Height)
return new Point(x, y);
}
}
throw new Exception("No Empty cells was found");
}

WinForms: highlighting X and Y axes

I'm making a program to graph parabolas, and I want to make the X and Y axes (the ones from (0,0)) a different color. I haven't found any options to do so, and the only solution I've found is to make a large grid and set its increment to half the graph's size. Is there an alternative?
I used the default chart control. I'd expect something like:
You can set Crossing for axis to move the axis to center of chart. Also you can set LineWidth for axis to make it thicker. Also you can set ArrowStyle to have an arrow at the end of axis.
For example, to have a chart like this:
Use such code:
private void Form1_Load(object sender, EventArgs e)
{
//Set Chart Margins
this.chart1.ChartAreas[0].Position.Auto = false;
this.chart1.ChartAreas[0].Position.X = 10;
this.chart1.ChartAreas[0].Position.Y = 10;
this.chart1.ChartAreas[0].Position.Width = 80;
this.chart1.ChartAreas[0].Position.Height = 80;
//Configure X Axis
this.chart1.ChartAreas[0].AxisX.Crossing = 0;
this.chart1.ChartAreas[0].AxisX.Interval = 1;
this.chart1.ChartAreas[0].AxisX.LabelStyle.Enabled = false;
this.chart1.ChartAreas[0].AxisX.LineWidth = 2;
this.chart1.ChartAreas[0].AxisX.ArrowStyle =
System.Windows.Forms.DataVisualization.Charting.AxisArrowStyle.Lines;
//Configure Y Axis
this.chart1.ChartAreas[0].AxisY.Crossing = 0;
this.chart1.ChartAreas[0].AxisY.Interval = 5;
this.chart1.ChartAreas[0].AxisY.LineWidth = 2;
this.chart1.ChartAreas[0].AxisY.LabelStyle.Enabled = false;
this.chart1.ChartAreas[0].AxisY.ArrowStyle =
System.Windows.Forms.DataVisualization.Charting.AxisArrowStyle.Lines;
//Set Chart Type
this.chart1.Series[0].ChartType =
System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Spline;
//Set Data
var p = new List<PointF>();
for (int i = -5; i <= 5; i++)
{
p.Add(new PointF(i, i * Math.Abs(i)));
}
this.chart1.DataSource = p;
this.chart1.Series[0].XValueMember = "X";
this.chart1.Series[0].YValueMembers = "Y";
this.chart1.Series[0].IsVisibleInLegend = false;
}

Get properties from object in tag

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.

c# adding New Button Depending on the # of items in mySQLWorkbench

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.

Problems with logic in c# script where images are loaded in a grid type look

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.

Categories