Changing properties of the sender object without knowing its name - c#

I am trying to change the BackColor of a PictureBox in a grid. The PictureBox is part of an array and the array has a chared event handler. I am having difficulty changing different PictureBox's depending on which one is clicked.
This is what I have so far:
private PictureBox[,] GameGrid = new PictureBox[20, 20];
public frmGame()
{
int x = 10;
int y = 10;
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 20; j++)
{
GameGrid[i, j] = new System.Windows.Forms.PictureBox();
setUpPicBox(x, y, i, j);
x += 11;
}
y += 11;
x = 10;
}
InitializeComponent();
}
public void setUpPicBox(int x, int y, int i, int j)
{
this.GameGrid[i, j].Location = new System.Drawing.Point(x, y);
this.GameGrid[i, j].Size = new System.Drawing.Size(10, 10);
this.GameGrid[i, j].BackColor = Color.Black;
this.GameGrid[i, j].Name = "btnGrid" + i + "-" + j;
this.GameGrid[i, j].Visible = true;
this.GameGrid[i, j].CreateGraphics();
this.GameGrid[i, j].Click += new System.EventHandler(this.picturebox_Click);
this.Controls.Add(GameGrid[i, j]);
}
private void picturebox_Click(object sender, EventArgs e)
{
}</code>
Any help would be appreciated

The event handler's sender parameter is the instance that raised the event. Here it is the PictureBox instance that the user has clicked. If you want to change its BackColor, you just cast the sender object to correct type and set the new color.
private void picturebox_Click(object sender, EventArgs e)
{
var pictureBox = sender as PictureBox;
if (pictureBox != null) {
pictureBox.BackColor = Color.Blue;
}
}

On your event handler, sender contains the object that caused the event handler to fire. So by casting it to the correct type, we can then access all the properties as per this example:
private void picturebox_Click(object sender, EventArgs e)
{
PictureBox pic = (PictureBox)sender;
MessageBox.Show(pic.Name);
}
Note: code untested, not got access to VS to test

Related

Labels don't move using Mouse events

I created 5 labels using a for. Inside the for I declared the properties of the labels, such as location, size, color, etc. and the possibility to move the labels using the mouse events:
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
Label letras = new Label();
letras.Height = alto;
letras.Width = ancho;
letras.BackColor = Color.Blue;
letras.ForeColor = Color.AntiqueWhite;
letras.Font = new Font("Arial", 60);
letras.TextAlign = ContentAlignment.MiddleCenter;
letras.BorderStyle = BorderStyle.FixedSingle;
letras.Left = 200 + (ancho + 20) * fila;
letras.Top = 60;
letras.Text = null;
letras.MouseDown += new MouseEventHandler(this.letras_MouseDown);
letras.MouseMove += new MouseEventHandler(this.letras_MouseMove);
letras.MouseUp += new MouseEventHandler(this.letras_MouseUp);
this.Controls.Add(letras);
}
}
Later in the code, I create the events which will make the labels move.
private void letras_MouseDown(object sender, MouseEventArgs e)
{
mousedown = true;
}
private void letras_MouseMove(object sender, MouseEventArgs e)
{
if (mousedown)
{
letras.Location = new Point(letras.Location.X + e.Location.X, letras.Location.Y + e.Location.Y);
}
}
private void letras_MouseUp(object sender, MouseEventArgs e)
{
mousedown = false;
}
but it isn't working. Any ideas? I think that could be an Indentation problem, but I'm not sure.
The sender argument received by the letras_MouseMove method is the Label so the first thing to do is perform a cast to a usable Label object. Then simply test the static Control.MouseButtons property to determine if the Left button is currently active. You calculated the offset correctly. I believe that all you really needed was to have the correct Label object. (Of course I tested it)
Some of the code you posted is not necessary and should be removed. This shows a minimal working example.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// This code stays the same
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
Label letras = new Label();
letras.Height = alto;
letras.Width = ancho;
letras.BackColor = Color.Blue;
letras.ForeColor = Color.AntiqueWhite;
letras.Font = new Font("Arial", 60);
letras.TextAlign = ContentAlignment.MiddleCenter;
letras.BorderStyle = BorderStyle.FixedSingle;
letras.Left = 200 + (ancho + 20) * fila;
letras.Top = 60;
letras.Text = null;
letras.MouseMove += new MouseEventHandler(this.letras_MouseMove);
this.Controls.Add(letras);
}
}
// This code is different
private void letras_MouseMove(object sender, MouseEventArgs e)
{
Label letra = (Label)sender;
if(MouseButtons == MouseButtons.Left)
{
// Here, your original calculation works OK once you have the correct Label object
letra.Location = new Point(letra.Location.X + e.Location.X, letra.Location.Y + e.Location.Y);
}
}
}
Haven't tested but replace:
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
letras = new Label();
With:
Label[] labels = Array.Empty<Label>();
private void Form1_Load(object sender, EventArgs e)
{
int alto = 100;
int ancho = 65;
for (byte fila = 0; fila < 5; fila++)
{
labels[fila] = new Label();
And replace every letras in the file with labels[(number)].

I wonder if there is a way to know which button from a list i clicked [duplicate]

This question already has answers here:
how to handle programmatically added button events? c#
(6 answers)
Closed 5 years ago.
Im coding in a windowsformapplication, c#
This is what i have done so far
List<Button> list = new List<Button>();
private void Form1_Load(object sender, EventArgs e)
{
for (int j = 0; j <= 13; j++)
{
for (int i = 0; i <= 13; i++)
{
Button ruta = new Button();
ruta.Location = new Point(0+ (i * 50), 0 + (j * 50));
ruta.Size = new Size(50, 50);
ruta.AutoSize = false;
ruta.Text = "";
ruta.TabStop = false;
list.Add(ruta);
this.Controls.Add(ruta);
}
}
}
What I now want is to be able to click on of these buttons and then change the text of a textbox to the index of the pressed button, I'm a real noob when it comes to C# so I have no idea what im doing atm.
What i thought about was something like
private void ruta_click(object sender, EventArgs e)
{
txtBox.text = list.SelectedItemIndex();
}
which obviously wont work since SelectedItemIndex() isnt a real method but just an example.
You should look for the index of sender in your list. The sender will be the button that was clicked, and generally sender will be the control that triggered the event. Also don't forget to add the handler to the button as you do not do taht in your for right now.
private void Form1_Load(object sender, EventArgs e)
{
for (int y = 0; y <= 13; y++)
{
for (int i = 0; i <= 13; i++)
{
Button ruta = new Button();
ruta.Location = new Point(0 + (i * 50), 0 + (y * 50));
ruta.Size = new Size(50, 50);
ruta.AutoSize = false;
ruta.Text = "";
ruta.TabStop = false;
ruta.Click += ruta_click;
list.Add(ruta);
this.Controls.Add(ruta);
}
}
}
private void ruta_click(object sender, EventArgs e)
{
txtBox.Text = list.IndexOf((Button)sender) + "";
}

WinForms button click event not firing

I don't get any errors from Visual Studio so I assumed that the code was right. When I run the code, I press the button (button1), but nothing happens.
private void button1_Click(object sender, EventArgs e)
{
int a = 0;
int b = 1;
int c = 1;
listBox1.Text += a.ToString();
listBox1.Text += b.ToString();
for (int i = 0; i < 20; i++)
{
c = b;
b = a + b;
a = c;
listBox1.Text += b.ToString();
}
}
Listbox's Text property won't work in this case, since it is used only to set or get the selected item in a listbox, add to the itemsource on each number, then it will work
private void button1_Click(object sender, EventArgs e)
{
int a = 0;
int b = 1;
int c = 1;
StringBuilder finalstring = new StringBuilder();
listBox1.Text += a.ToString();
listBox1.Text += b.ToString();
for (int i = 0; i < 20; i++)
{
c = b;
b = a + b;
a = c;
listBox1.Items.Add(b);
}
}
Does button have button1_Click registered as an event?
You can do it via your code by adding button1.Click += button1_Click, or double clicking it in your form designer.
If this still does not work, put a breakpoint on the code to see if it is executed.

Sending a variable in a C# EventHandler?

How can I send a variable with a newly created EventHandler?
The code I have is something like:
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += new EventHandler(buttonClick);
}
private void buttonClick(object sender, EventArgs e)
{
MessageBox.Show();
}
How can I can make it like
buttonX.Click += new EventHandler(buttonClick , i);
private void buttonClick(object sender, EventArgs e, int i)
{
MessageBox.Show(i.toString());
}
Closures are grand. You can use lambda notation:
buttonX.Click += (sender, e) => buttonClick(sender, e, i);
or anonymous delegate notation:
buttonX.Click += delegate (object sender, EventArgs e) { buttonClick(sender, e, i); };
However, you're going to have trouble if you capture the loop variable.
Instead, do
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
var i_copy = i;
buttonX.Click += (sender, e) => buttonClick(sender, e, i_copy);
}
Given your scenario, just utilize the Tag property; don't mix the solution with the Click event; you don't need to "pass" i every time to the event; just tag it to the control since it's always the same; that way you don't have to worry about closure.
Change your code to this:
for (int i = 0; i < 5; i++)
{
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += new EventHandler(buttonClick);
buttonX.Tag = i;
}
private void buttonClick(object sender, EventArgs e)
{
MessageBox.Show(((Button)sender).Tag.ToString());
}
You would create a class derived from EventArgs that carries the additional data points that you want.
http://msdn.microsoft.com/en-us/library/system.eventargs.aspx
So instead of just using EventArgs you would create an EventArgs for the event you are raing.
public class ButtonClickedEventArgs : EventArgs
{
public int EventInteger { get; private set; }
public ButtonClickedEventArgs(int i)
{
EventInteger = i;
}
}
And then when you raise the event you would create the ButtonClickedEventArgs class and pass that with the EventHandler.
You can't do that, but what you can do is use an intermediate lambda:
for (int i = 0; i < 5; i++)
{
int j = i; // Need to do this to fix closure issue
Button buttonX = new Button();
buttonX.Location = new Point(0, 0 + offset);
buttonX.Size = new Size(310, 48);
buttonX.Click += (sender, e) => {
buttonClick(sender, e, j);
};
}
private void buttonClick(object sender, EventArgs e, int i)
{
MessageBox.Show(i.toString());
}

Change SelectedTab of TabControl on MouseOver

I have a Windows Forms project with a TabControl.
Does anyone know how to change the SelectedTab when you hover over it with the pointer?
You can use TabControl's MouseMove event to detect whether your mouse is present on any tab and then can select it:
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
Rectangle mouseRect = new Rectangle(e.X, e.Y, 1, 1);
for (int i = 0; i < tabControl1.TabCount; i++)
{
if (tabControl1.GetTabRect(i).IntersectsWith(mouseRect))
{
tabControl1.SelectedIndex = i;
break;
}
}
}
Try this:
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
for (int i = 0; i < tabControl1.TabCount; i++)
{
if (tabControl1.GetTabRect(i).Contains(e.X, e.Y))
{
tabControl1.SelectedIndex = i;
break;
}
}
}

Categories