How to move PictureBox in TableLayoutPanel grid from keyboard? - c#

I'm quite new at C#, but I'm trying to move a picturebox, by pressing the up-down-left-right keys from the keyboard, in a grid TableLayoutPanel(I made the grid at runtime). The grid is 23x23, has brickblock images border(each cell at the border contains a brickblock image in an imagebox) and an imagebox with a mouse in the middle. What I'm trying to do is moving the mouse image from the central cell(which is 11x11) in another cell by pressing one of the control keys mentioned above. It seems I can't get a grip on the idea of eventHandler... . The code works very good 'till I want to make the picturebox move. I've put the whole code, maybe the problem is in a place I didn't notice, but I think that the problem is KeyDown += new KeyEventHandler(Form2_KeyDown) or/end private void Form2_KeyDown(object sender, KeyEventArgs e){...} .
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace IndividualProject
{
public partial class Form2 : Form
{
PictureBox picturebox5 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
public Form2()
{
InitializeComponent();
// MaximizeBox = false;
//size
int h = Screen.PrimaryScreen.WorkingArea.Height / 2;
int w = Screen.PrimaryScreen.WorkingArea.Width / 2;
Size = new Size(w / 2 + w / 7, h + h / 4 + h / 7);
//location
StartPosition = FormStartPosition.CenterScreen;
//form style
FormBorderStyle = FormBorderStyle.FixedSingle;
//menuStrip1.BackColor = Color.Beige;
//lives and score container
#region livesAndScore
lasContainer.Size = new Size(Width / 2 + Width / 3 + Width / 7, Height / 13);
lasContainer.BackColor = Color.Lavender;
lasContainer.BorderStyle = BorderStyle.Fixed3D;
lasContainer.Dock = DockStyle.Top;
lasContainer.SplitterDistance = Width / 2 - Width / 69;
//labels
lives.Location = new Point(lasContainer.Panel1.Width / 12, lives.Height / 2);
score.Location = new Point(lasContainer.Panel2.Width / 12, score.Height / 2);
//picturebox
live3.Location = new Point(lasContainer.Panel1.Width / 3, lives.Height / 2);
live2.Location = new Point(lasContainer.Panel1.Width / 2, lives.Height / 2);
live1.Location = new Point(lasContainer.Panel1.Width / 2 + lasContainer.Panel1.Width / 6, lives.Height / 2);
#endregion livesAndScore
//gamePanel
gamePanel.Dock = DockStyle.Fill;
gamePanel.BackColor = Color.SkyBlue;
gamePanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single; // REMOVE WHEN FINISHED !!!!!!!!!!!
//making the grid
#region grid
gamePanel.ColumnCount = 23;
gamePanel.RowCount = 23;
gamePanel.ColumnStyles.Clear();
gamePanel.RowStyles.Clear();
int iIndex, jIndex = 0;
for (iIndex = 0; iIndex < gamePanel.ColumnCount; iIndex++)
{
gamePanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 4.34F));
gamePanel.RowStyles.Add(new RowStyle(SizeType.Percent, 4.34F));
}
#endregion grid
while(jIndex < gamePanel.ColumnCount)
{
#region picturebox1
PictureBox picturebox1 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox1, jIndex, 0);
picturebox1.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox1
#region picturebox2
PictureBox picturebox2 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if (jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox2, 0, jIndex + 1);
picturebox2.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox2
#region picturebox3
PictureBox picturebox3 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0)
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox3, gamePanel.ColumnCount - 1 - jIndex, gamePanel.RowCount - 1);
picturebox3.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox3
#region picturebox4
PictureBox picturebox4 = new PictureBox
{
Visible = true,
Anchor = AnchorStyles.Top,
SizeMode = PictureBoxSizeMode.Normal,
BackColor = Color.Sienna,
Dock = DockStyle.Fill,
Margin = new Padding(0),
};
if(jIndex < gamePanel.ColumnCount - 1)
{
gamePanel.Controls.Add(picturebox4, gamePanel.ColumnCount - 1, gamePanel.RowCount - 1 - jIndex - 1);
picturebox4.ImageLocation = #"..\..\ResourcesPh\brickblock.png";
}
#endregion picturebox4
jIndex++;
}
//the starting point of the mouse
#region mouseStartPoint
//PictureBox picturebox5 = new PictureBox
//{
// Visible = true,
// Anchor = AnchorStyles.Top,
// SizeMode = PictureBoxSizeMode.Normal,
// BackColor = Color.Sienna,
// Dock = DockStyle.Fill,
// Margin = new Padding(0)
//};
gamePanel.Controls.Add(picturebox5, 11, 11);
picturebox5.ImageLocation = #"..\..\ResourcesPh\mouse.png";
#endregion mouseStartPoint
KeyDown += new KeyEventHandler(Form2_KeyDown);
}
private void Form2_KeyDown(object sender, KeyEventArgs e)
{
int x = 11, y = 11;
if (e.KeyCode == Keys.Right)
x += 1;
if (e.KeyCode == Keys.Left)
x -= 1;
if (e.KeyCode == Keys.Up)
y -= 1;
if (e.KeyCode == Keys.Down)
y += 1;
gamePanel.Controls.Remove(picturebox5);
gamePanel.Controls.Add(picturebox5, x, y);
picturebox5.ImageLocation = #"..\..\ResourcesPh\mouse.png";
Refresh();
}
private void howToPlayToolStripMenuItem_Click(object sender, EventArgs e)
{
Hide();
Form3 f3 = new Form3();
f3.FormClosed += (s, args) => Close(); //event handler on closing Form2 after Form3 is opened
f3.Show();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
TableLayoutPanel Grid

You are always setting the starting position back to 11, 11 on every key click. Move your declaration outside of that scope:
int x = 11, y = 11;
private void Form2_KeyDown(object sender, KeyEventArgs e) {

Here's a greatly simplified approach for moving your mouse, I get straight to the point and kept things to a bare minimum, yet effective :D
Here are the tiles I've used:
And here's the code !
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
private Dictionary<int, Image> _dictionary;
private Size _imageSize;
private int[] _level;
private Size _levelSize;
private Point _mousePos;
public Form1()
{
InitializeComponent();
pictureBox1.Paint += PictureBox1_Paint;
}
private void Form1_Load(object sender, EventArgs e)
{
InitializeLevel();
Redraw();
}
private void InitializeLevel()
{
var imageEmpty = Image.FromFile("empty.png");
var imageMouse = Image.FromFile("mouse.png");
var imageWall = Image.FromFile("wall.png");
_level = new[]
{
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 1, 1, 1, 0,
0, 0, 0, 0, 0
};
_levelSize = new Size(5, 5);
_imageSize = new Size(25, 25);
_dictionary = new Dictionary<int, Image>();
_dictionary.Add(0, imageWall);
_dictionary.Add(1, imageEmpty);
_dictionary.Add(2, imageMouse);
_mousePos = new Point();
}
private void Redraw()
{
pictureBox1.Invalidate();
}
private void PictureBox1_Paint(object sender, PaintEventArgs e)
{
var graphics = e.Graphics;
graphics.Clear(Color.Transparent);
// draw level
var i = 0;
foreach (var tile in _level)
{
var x = i % _levelSize.Width;
var y = i / _levelSize.Width;
var image = _dictionary[tile];
graphics.DrawImage(image, new Point(x * _imageSize.Width, y * _imageSize.Height));
i++;
}
// draw hero !
graphics.DrawImage(_dictionary[2], _mousePos);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
var up = keyData == Keys.Up;
var down = keyData == Keys.Down;
var left = keyData == Keys.Left;
var right = keyData == Keys.Right;
var processed = up || down || left || right;
if (!processed) return base.ProcessCmdKey(ref msg, keyData);
// move the hero !
var x = 0;
var y = 0;
if (left) x--;
if (right) x++;
if (up) y--;
if (down) y++;
_mousePos.X += x;
_mousePos.Y += y;
Redraw();
return true;
}
}
}
Obviously you'll still want to check collisions, define your logic and such ...
Go on and give it a try !
Welcome to SO and good luck :D

Related

C# ToolStripProfessionalRender, event OnRenderItemText applied only on the first item

I'm drawing a custom toolstrip using ToolStripProfessionalRender and editing the OnRenderItemText event as follows:
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.Item.ForeColor = Clr.White;
e.Item.TextAlign = ContentAlignment.MiddleLeft;
e.Item.Alignment = ToolStripItemAlignment.Left;
base.OnRenderItemText(e);
if (e.Item.GetType() == typeof(ToolStripDropDownButton))
{
ToolStripDropDownButton tsmi = (ToolStripDropDownButton)e.Item;
if (tsmi.HasDropDownItems && tsmi.OwnerItem == null)
{
Rectangle bounds = tsmi.Bounds;
bounds.X = bounds.Right - 25;
bounds.Width = 25;
bounds.Y = 10;
// Draw the corner
Graphics G = e.Graphics;
SolidBrush brushw = new SolidBrush(Color.FromArgb(70,70,70));
Point[] points =
{
new Point(bounds.Right - 3, bounds.Height - 11), // point top right
new Point(bounds.Right - 3, bounds.Bottom - 14), // point bottom right
new Point(bounds.Right - 10, bounds.Bottom - 14) // point bottom left
};
G.FillPolygon(brushw, points);
}
}
}
and basically the output i'm trying to obtain is the following:
So drawing a little triangle on the bottom right corner when i got a ToolStripDropDownButton. The problem is that the little triangle is drawn only first item.
To end up the question i draw this toolstrip dynamically using a function that adds a dropdownbutton at each call.
ToolStripDropDownButton m_Item = new ToolStripDropDownButton(text, image);
m_Item.ImageAlign = ContentAlignment.MiddleCenter;
m_Item.ImageScaling = ToolStripItemImageScaling.None;
m_Item.Name = name;
m_Item.ForeColor = Color.White;
m_Item.BackColor = Color.FromArgb(95, 95, 95);
m_Item.Padding = new Padding(5);
m_Item.ShowDropDownArrow = false;
m_Item.Paint += new PaintEventHandler(this.PaintButtonBorder);
if (tabPage != null)
m_Item.Click += (sender, e) => AddClickTab(sender, e, tabPage);
((ToolStripDropDownMenu)m_Item.DropDown).ShowImageMargin = false;
((ToolStripDropDownMenu)m_Item.DropDown).ShowCheckMargin = false;
((ToolStripDropDownMenu)m_Item.DropDown).Cursor = Cursors.Hand;
toolStrip1.Items.Add(m_Item);
if (SubItems != null)
{
for(int i = 0; i < SubItems.Length; i++)
{
object[] subitem = (object[])SubItems[i];
FnAddToolStripMenuItem(
subitem[0].ToString(),
subitem[1].ToString(),
(Bitmap)subitem[2],
m_Item,
(TabPage)subitem[3]
);
}
}
Am i missing some "new" maybe?
Override the OnRenderItemText method only to draw the text part as it says, and/or to set the default properties used when rendering the text. To change the look and the shape of the arrows of the dropdown items, override the OnRenderArrow method.
Example
using System.Drawing;
using System.Drawing.Drawing2D;
protected override void OnRenderArrow(ToolStripArrowRenderEventArgs e)
{
// Optional: to be the default color of the arrows.
e.ArrowColor = Color.FromArgb(70, 70, 70);
if (e.Item is ToolStripDropDownButton item && item.OwnerItem == null)
{
var g = e.Graphics;
var r = new Rectangle(item.Bounds.Width - 10, item.Bounds.Height - 10, 8, 8);
g.SmoothingMode = SmoothingMode.AntiAlias;
g.PixelOffsetMode = PixelOffsetMode.Half;
using (var br = new SolidBrush(e.ArrowColor))
g.FillPolygon(br, new[]
{
new Point(r.Left, r.Bottom),
new Point(r.Right, r.Top),
new Point(r.Right, r.Bottom)
});
g.SmoothingMode = SmoothingMode.None;
g.PixelOffsetMode = PixelOffsetMode.Default;
}
else
base.OnRenderArrow(e);
}
protected override void OnRenderItemText(ToolStripItemTextRenderEventArgs e)
{
e.Item.ForeColor = Color.White;
e.Item.TextAlign = ContentAlignment.MiddleLeft;
e.Item.Alignment = ToolStripItemAlignment.Left;
base.OnRenderItemText(e);
}
Make sure to enable the ShowDropDownArrow property of the dropdown buttons. So comment this m_Item.ShowDropDownArrow = false;.
If you are also interested to change the color according to the current state of the dropdown button (Selected, Pressed), then you can do for example:
using (var br = new SolidBrush(item.Selected
? Color.FromArgb(150, 150, 150) : item.Pressed
? Color.FromArgb(100, 100, 100) :
Color.FromArgb(70, 70, 70)))
//...

C# find panels adjecent to panel being clicked

I'm trying to make a little game where you turn all panels green.
I do this by getting a 5x5 grid of panels, every panel has a 1/3 chance to be green, otherwise it will start as red.
my problem is that i do not have the slightest clue how to start the main problem.
when i click a panel, the panel above, left ,right and below need to change color aswell.
at the moment i do not know how to identify which panels are next to the one being clicked.
this is my code:
public partial class Form1 : Form
{
Panel[,] PanelArray = new Panel[5,5];
Random R = new Random();
int R1;
public Form1()
{
InitializeComponent();
for (int r = 0; r < 5; r++)
{
for (int c = 0; c < 5; c++)
{
R1 = R.Next(0, 3);
PanelArray[r, c] = new Panel
{
Size = new Size(50, 50),
Location = new Point(PanelContainer.Width / 5 * c, PanelContainer.Height / 5 * r),
BackColor = Color.Red,
BorderStyle = BorderStyle.Fixed3D
};
PanelArray[r, c].Click += new EventHandler(PanelArray_Click);
if (R1 == 1) PanelArray[r, c].BackColor = Color.Green;
PanelContainer.Controls.Add(PanelArray[r, c]);
}
}
}
private void PanelArray_Click(object sender, EventArgs e)
{
Panel P = (Panel)sender;
if (P.BackColor == Color.Red) P.BackColor = Color.Green;
else if (P.BackColor == Color.Green) P.BackColor = Color.Red;
if (CheckWin()) MessageBox.Show("test");
}
private bool CheckWin()
{
//foreach panel green blah blah
return false;
}
}
}`
You can use the Tag property in your Panel objects to store some information.
PanelArray[r, c] = new Panel
{
Size = new Size(50, 50),
Location = new Point(PanelContainer.Width / 5 * c, PanelContainer.Height / 5 * r),
BackColor = Color.Red,
BorderStyle = BorderStyle.Fixed3D,
Tag = (Row: r, Column: c)
};
In your PanelArray_Click method, you can get the indexes:
var indexes = ((int Row, int Column))P.Tag;
var row = indexes.Row;
var column = indexes.Column;
// Todo: your logic here
In the Tag property, you can store any object, so you can create some class to store data, if you need.
Other solution is two for loops, to get the indexes, like:
private (int Row, int Column) GetIndexes(Panel panel)
{
for (int x = 0; x < PanelArray.GetLength(0); x++)
{
for (int y = 0; y < PanelArray.GetLength(1); y++)
{
if (PanelArray[x, y] == panel)
{
return (x, y);
}
}
}
throw new Exception("Not found.");
}
And then you can use in your PanelArray_Click method:
var indexes = this.GetIndexes(P);
var row = indexes.Row;
var column = indexes.Column;
// Todo: your logic here
Here is easy trick to get row and column. Create a class that inherits the Panel and adds a row and column. See code below
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
MyPanel[,] PanelArray = new MyPanel[5, 5];
Random R = new Random();
int R1;
public Form1()
{
InitializeComponent();
for (int r = 0; r < 5; r++)
{
for (int c = 0; c < 5; c++)
{
R1 = R.Next(0, 3);
PanelArray[r, c] = new MyPanel
{
Size = new Size(50, 50),
Location = new Point(PanelContainer.Width / 5 * c, PanelContainer.Height / 5 * r),
BackColor = Color.Red,
BorderStyle = BorderStyle.Fixed3D,
row = r,
col = c
};
PanelArray[r, c].Click += new EventHandler(PanelArray_Click);
if (R1 == 1) PanelArray[r, c].BackColor = Color.Green;
PanelContainer.Controls.Add(PanelArray[r, c]);
}
}
}
private void PanelArray_Click(object sender, EventArgs e)
{
MyPanel P = sender as MyPanel;
int row = P.row;
int col = P.col;
if (P.BackColor == Color.Red) P.BackColor = Color.Green;
else if (P.BackColor == Color.Green) P.BackColor = Color.Red;
if (CheckWin()) MessageBox.Show("test");
}
private bool CheckWin()
{
//foreach panel green blah blah
return false;
}
}
public class MyPanel : Panel
{
public int row { get; set; }
public int col { get; set; }
}
}

How to draw after button click?

protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
var cp = new Point(Width / 2, Height / 2);
DrawGradientCircle(e.Graphics, cp, 100);
}
private void DrawGradientCircle(Graphics gr, Point cp, float radius)
{
var path = new GraphicsPath();
path.AddEllipse(cp.X - radius, cp.Y - radius, 2 * radius, 2 * radius);
using (var brush = new PathGradientBrush(path))
{
var blends = new ColorBlend(7);
blends.Colors[0] = Color.Violet;
blends.Positions[0] = 0;
blends.Colors[1] = Color.Blue;
blends.Positions[1] = 0.16f;
blends.Colors[2] = Color.Aqua;
blends.Positions[2] = 0.32f;
blends.Colors[3] = Color.Lime;
blends.Positions[3] = 0.48f;
blends.Colors[4] = Color.Yellow;
blends.Positions[4] = 0.64f;
blends.Colors[5] = Color.Orange;
blends.Positions[5] = 0.82f;
blends.Colors[6] = Color.Red;
blends.Positions[6] = 1;
brush.InterpolationColors = blends;
gr.FillPath(brush, path);
}
}
There is my code - i just want to draw the circle after button click, but how to do it?
But I don't know how make a link
If I understood you right, you could have a boolean variable and set it to true when you click the button... something like:
private bool _buttonClicked = false;
void myButton_Click(object sender, EventArgs e)
{
_buttonClicked = true;
this.Invalidate(); // <-- invalidate the form so it's repainted
this.Update(); // <-- optional: force a synchronous repaint
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if(!_buttonClicked) return;
// this will only happen after button is clicked
var cp = new Point(Width / 2, Height / 2);
DrawGradientCircle(e.Graphics, cp, 100);
}
Don't forget to assign myButton_Click to the button's Click event

c# gomoku game label array

I am trying to make a simple five in a row (gomoku) game for two players using windows forms and c#. I put a picturebox with a picture and stretched it out on the form. Now I want to put labels at all the intersections on the picture board so a user can click them and change their background color to black or white.
How can I make the labels created clickable on the form?
public partial class Form1 : Form
{
int labelCount = 0;
int iteration = 0;
public Form1()
{
InitializeComponent();
Label[] board = new Label[361];
for (int i = 0; i < 361; i++)
{
board[i] = new Label
{
Name = "label" + i,
Height = 55,
Width = 55,
MinimumSize = new Size(55, 55),
Text = "label " + i
};
}
int x = 0;
int y = 0;
foreach (var Label in board)
{
if (x >= 580)
{
x = 0;
y = y + Label.Height + 55;
}
Label.Location = new Point(x, y);
this.Controls.Add(Label);
x += Label.Width;
}
}
}
Should I make a one-dimensional [361] or two-dimensional array[{A,1}, {A,2}....{D,1}] to easily check for a winner? How can I connect it to the created labels so the array data corresponds to the objects on the board?
Well Sorry If don`t understand your question. For the Q.1 to add 361 labels you can try the code below. I hope it will help you.
public int x = 0;
public int y = 0;
private Label[] moku = new Label[361];
private void Form1_Load(object sender, EventArgs e)
{
try
{
for (int i = 0; i < 361; i++)
{
moku[i] = new Label();
moku[i].Parent = pictureBox1;//make the picturebox parent
moku[i].Location = new Point(x, y);
moku[i].Text = "O";
moku[i].Name = "moku" + i;
moku[i].BackColor = Color.Transparent;
pictureBox1.Controls.Add(moku[i]);
y += 55;
if (y >= 361) { x += 55; y = 0; x+=55; }
}
}catch(Exception er)
{
MessageBox.Show(er.ToString());
}
}
I prefer using a 2D array because it's easier if you want to check the surrounding boxes.
Form design:
Full source:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication6
{
public enum Player
{
Empty = 0,
White,
Black
}
public partial class Form1 : Form
{
// initialize board of 5x5
private Player[,] board = new Player[5, 5];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
DrawBoard();
}
private void DrawBoard()
{
for (var i = 0; i <= board.GetUpperBound(0); i++)
{
for (var j = 0; j <= board.GetUpperBound(1); j++)
{
// for name and text
var name = string.Format("{0}, {1}", i, j);
var label = new Label()
{
Name = name, // name of label
Size = new Size(55, 55),
BorderStyle = BorderStyle.FixedSingle,
Location = new Point(i * 55, j * 55), // location depends on iteration
Text = name
};
label.Click += ClickLabel; // subscribe the Click event handler
pictureBox1.Controls.Add(label); // add label to a container
}
}
}
// this event handler will handle all the labels click event
private void ClickLabel(object sender, EventArgs e)
{
var label = (Label)sender; // this is the label that you click
var x = Convert.ToInt32(label.Name.Split(',')[0]);
var y = Convert.ToInt32(label.Name.Split(',')[1]);
// change the color
if (radPlayerBlack.Checked)
{
// Player Black
label.ForeColor = Color.White;
label.BackColor = Color.Black;
board[x, y] = Player.Black;
}
else
{
// Player White
label.ForeColor = Color.Black;
label.BackColor = Color.White;
board[x, y] = Player.White;
}
}
}
}
You can check the value of the 2D array for black or white. Here's the value when I QuickWatch it in Visual Studio.

Change color of panel when mouse clicked?

I am very new to visual C#
I want to make a ticket booking system (like in cinemas), I have created the seats using panel, each seating is 40 * 40
Here's my code:
private void panel2_Paint(object sender, PaintEventArgs e)
{
int a, b;
for (a = 0; a <= 1; a++)
{
for (b = 0; b < 12; b++)
{
Graphics g = e.Graphics;
g.FillRectangle(new SolidBrush(Color.White), b * 40, a * 40, 40, 40);
g.DrawRectangle(new Pen(Color.Black), b * 40, a * 40, 40, 40);
}
}
}
Now I want to change the color of each seating by a mouse click to show what seat has been selected; but so far no luck
You would be better off creating seperate controls for each of your selected seats and handling their Click events. In this example I added 24 PictureBox's to the Panel. I then placed their index in the Tag Property of the Control and attached a common Click Event Handler. I am also using a Bool array to keep track of selected status.
public partial class Form1 : Form
{
bool[] selected = new bool[24];
public Form1()
{
InitializeComponent();
foreach (PictureBox pb in panel1.Controls)
{
pb.Click += new EventHandler(pictureBox_Click);
}
}
private void pictureBox_Click(object sender, EventArgs e)
{
PictureBox pb = (PictureBox)sender;
int index ;
if (int.TryParse(pb.Tag.ToString(), out index))
{
if (selected[index])
{
selected[index] = false;
pb.BackColor = Color.White;
}
else
{
selected[index] = true;
pb.BackColor = Color.Red;
}
}
}
}
You can use what you have if you create a boolean array to store the state of the Seat, use the Panel's MouseDown Event to set the variable and Invalidate the screeen rectangle that is accociated with your seat.
Something like this.
public partial class Form1 : Form
{
bool[,] selected = new bool[2,12];
public Form1()
{
InitializeComponent();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
int a, b;
for (a = 0; a <= 1; a++)
{
for (b = 0; b < 12; b++)
{
if (selected[a, b])
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red), b * 40, a * 40, 40, 40);
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.White ), b * 40, a * 40, 40, 40);
}
e.Graphics.DrawRectangle(new Pen(Color.Black), b * 40, a * 40, 40, 40);
}
}
}
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
int xPos, yPos;
xPos = e.X / 40;
yPos = e.Y / 40;
if ((xPos > 11) || (yPos > 1)) return;
if(selected[yPos,xPos])
selected[yPos, xPos] = false;
else
selected[yPos, xPos] = true;
((Panel)sender).Invalidate(new Rectangle(xPos * 40,yPos *40,40,40)) ;
}
}
Rather than using a Graphics object and drawing directly to the form, you may be able to get away with simply setting the BackColor property of the control that corresponds to the selected seat when the OnMouseClick event fires.

Categories

Resources