How to access to a specific PictureBox.EventHandler that was created programmatically? - c#

I am making a Scorebar from 1-10 where every number is one picture of a small grey cube.
Like this:
🟩🟩🟩🟩🟩⬛⬛⬛⬛⬛ (This would be a score of 5)
Now I want to change the cube images to green ones, when the MouseDown Event is triggered, but I don't know who to tell the program.
Pic of Scorebar
private void BtnDebug_Click(object sender, EventArgs e)
{
int xPos = 200;
int yPos = 100;
PictureBox[] ScoreGameplay = new PictureBox[100];
for (int i = 0; i < 10; i++)
{
ScoreGameplay[i] = new PictureBox();
ScoreGameplay[i].Name = "ScoreGameplay" + i;
ScoreGameplay[i].Size = new Size(18, 18);
ScoreGameplay[i].Location = new Point(xPos, yPos);
ScoreGameplay[i].Image = Image.FromFile(#"img\icons\score_empty.png");
ScoreGameplay[i].MouseEnter += new EventHandler(Score_MouseEnter);
ScoreGameplay[i].MouseLeave += new EventHandler(Score_MouseLeave);
ScoreGameplay[i].MouseDown += new MouseEventHandler(Score_MouseDown);
this.Controls.Add(ScoreGameplay[i]);
xPos += 18;
}
This part works without an issue, but here we go:
private void Score_MouseDown(object sender, EventArgs e)
{
if (sender is PictureBox pBox)
{
// ???
}
}
How do I tell know which Index of the Array in BtnDebug_Click has triggered the MouseDown?
For example:
The 7th PictureBox has been clicked; now I want to change the images from PictureBoxes 1-7 to the green ones.
Anyone has a smart solution for this?

Simply you can do that
private void BtnDebug_Click(object sender, EventArgs e)
{
int xPos = 200;
int yPos = 100;
PictureBox[] ScoreGameplay = new PictureBox[100];
for (int i = 0; i < 10; i++)
{
ScoreGameplay[i] = new PictureBox();
ScoreGameplay[i].Name = $"ScoreGameplay{i}";
ScoreGameplay[i].Size = new Size(18, 18);
ScoreGameplay[i].Location = new Point(xPos, yPos);
ScoreGameplay[i].Image = Image.FromFile(#"img\icons\score_empty.png");
ScoreGameplay[i].MouseEnter += new EventHandler(Score_MouseEnter);
ScoreGameplay[i].MouseLeave += new EventHandler(Score_MouseLeave);
ScoreGameplay[i].MouseDown += new MouseEventHandler(Score_MouseDown);
this.Controls.Add(ScoreGameplay[i]);
xPos += 18;
}
}
and in Score_MouseDown
private void Score_MouseDown(object sender, EventArgs e)
{
string imageName = ((PictureBox)sender).Name; // get the name of the clicked image
string imageIndex = imageName.Substring(13); // get the text after 13 chars
}

Related

c# Dynamically creating an EventHandler in a loop

I am trying to dynamically create an array of images on a form. THe images are rendering okay, but I cannot work out how to create the eventHandlers.
pictureBox.Click += new System.EventHandler(this.pictureBox);
This line is causing be problems.
private void frmBorderlessMain_Load(object sender, EventArgs e)
{
int top = 10;
int left = 10;
int width = 200;
int height = 150;
var uutNames = MyObject.GetNames().ToArray();
var uutImages = MyObject.GetImages().ToArray();
for (int i = 0; i < uutNames.Length; i++)
{
System.Windows.Forms.PictureBox pictureBox = new System.Windows.Forms.PictureBox();
Image newImage = Image.FromFile(uutImages[i]+".png");
pictureBox.Image = ((System.Drawing.Image)(newImage));
pictureBox.Location = new System.Drawing.Point(left, top);
pictureBox.Name = "pictureBox"+i;
pictureBox.Size = new System.Drawing.Size(200, 150);
pictureBox.SizeMode =
System.Windows.Forms.PictureBoxSizeMode.Zoom;
pictureBox.TabIndex = i;
pictureBox.TabStop = false;
pictureBox.Click += new System.EventHandler(this.pictureBox);
this.tabPage1.Controls.Add(pictureBox);
left += width + 10;
if ( (i > 0 ) && (i % 3) == 0)
{
top += height + 10;
left = 10;
}
}
}
Additional Info:
Upon clicking the image I would like a new form to open displaying details about the entity that was clicked. It will be the same form, but will be loaded with data depending on which image was clicked on.
pictureBox.Click += new System.EventHandler(this.pictureBox);
That is not how event handlers are used.
Lambda:
pictureBox.Click += (sender, eventArgs) => Console.WriteLine("HELP I WAS CLICKED OMG");
Or with a function:
pictureBox.Click += PictureBox_Click;
....
private void PictureBox_Click(object sender, EventArgs e)
{
Console.WriteLine("Stop clicking me >:(");
}

Add dynamic controls (PictureBox) with position data read from text file

I have text file with one line in it. The line looks like this:
100 300 200 400 658 487 2636 254 245 527
These numbers represent X and Y coordinates of points (first and second are X and Y of point N1, third and fourth are X and Y of point N2,...., ).
I read the file and put it in an array.
My next step is to draw the picture boxes in a container (panel).
The problem is that the panel is only showing the control with last coordinates.
private void CreateBlastHole(string[] pointCoordinate)
{
PictureBox blastHole = new PictureBox();
blastHole.Height = 15;
blastHole.Width = 15;
blastHole.BackColor = Color.Blue;
for (int i = 0; i < pointCoordinate.Length; i++)
{
blastHole.Left = int.Parse(pointCoordinate[i]);
i = i + 1;
blastHole.Top = int.Parse(pointCoordinate[i]);
drawingPanel.Controls.Add(blastHole);
}
blastHole.Click += new EventHandler(BlastHole_Click);
ToolTip tooltip1 = new ToolTip();
// Set up delays for the tooltip
tooltip1.AutoPopDelay = 5000;
tooltip1.InitialDelay = 1000;
tooltip1.ReshowDelay = 500;
// Force the tooltip text to be displayed whether or not the form is active.
tooltip1.ShowAlways = true;
// Set up the tooltip text for the controls
int axisX = blastHole.Location.X;
int axisY = blastHole.Location.Y;
string coordinates = "Точка N " + blastHole.Name + "X = " + axisX.ToString() + " Y = " + axisY.ToString();
tooltip1.SetToolTip(blastHole, coordinates);
}
private void BlastHole_Click(object sender, EventArgs e)
{
MessageBox.Show(MousePosition.X.ToString(), MousePosition.Y.ToString());
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void openButton_Click(object sender, EventArgs e)
{
openFileDialogPoints.ShowDialog();
string name = openFileDialogPoints.FileName;
File.ReadAllLines(name);
string[] points = File.ReadAllText(name).Split( );
CreateBlastHole(points);
}
private void drawingPanel_Paint(object sender, PaintEventArgs e)
{
}
private void buttonDrawHole_Click(object sender, EventArgs e)
{
}
You need to move your code inside the for-loop, to create more than one PictureBox. Currently, you are only creating one instance, reusing it for each blastHole.
Try something like this instead:
private void CreateBlastHole(string[] pointCoordinate)
{
for (int i = 0; i < pointCoordinate.Length; i++)
{
PictureBox blastHole = new PictureBox();
blastHole.Height = 15;
blastHole.Width = 15;
blastHole.BackColor = Color.Blue;
blastHole.Left = int.Parse(pointCoordinate[i]);
i = i + 1;
blastHole.Top = int.Parse(pointCoordinate[i]);
drawingPanel.Controls.Add(blastHole);
blastHole.Click += new EventHandler(BlastHole_Click);
ToolTip tooltip1 = new ToolTip();
// Set up delays for the tooltip
tooltip1.AutoPopDelay = 5000;
tooltip1.InitialDelay = 1000;
tooltip1.ReshowDelay = 500;
// Force the tooltip text to be displayed whether or not the form is active.
tooltip1.ShowAlways = true;
// Set up the tooltip text for the controls
int axisX = blastHole.Location.X;
int axisY = blastHole.Location.Y;
string coordinates = "Точка N " + blastHole.Name + "X = " + axisX.ToString() + " Y = " + axisY.ToString();
tooltip1.SetToolTip(blastHole, coordinates);
}
}

Drag and Drop dynamically generated images [C#/Windows Store App]

i have dynamically generated images. if i click last added image it dragging normally, but when i click to other image and tried to drag it, last added image dragging again.
here is my codes
void setDynamicImages()
{
for (int i = 0; i < 10; i++)
{
RectMeyve = new Rectangle();
IMG_meyve = new Image();
IMG_meyve.Height = 36 * ratioHeight;
IMG_meyve.Width = 51 * ratioWidth;
randMeyveCesit = Rand.Next(5);
IMG_meyve.Source = new BitmapImage(new Uri("ms-appx:///Assets/Sayfa10/dusen_meyveler/cilek_0" + (randMeyveCesit + 1) + ".png"));
IMG_meyve.Tag =randMeyveTur;
pressedIMGTag =randMeyveTur;
RectMeyve.Fill = new SolidColorBrush(Colors.Aqua);
RectMeyve.Height = IMG_meyve.ActualHeight;
RectMeyve.Width = IMG_meyve.Width;
Canvas.SetLeft(RectMeyve, Canvas.GetLeft(IMG_meyve));
Canvas.SetTop(RectMeyve, Canvas.GetTop(IMG_meyve));
RectMeyve.Opacity = 0.6;
RectMeyve.IsHitTestVisible = false;
IMG_meyve.ActualWidth, IMG_meyve.ActualHeight);
this.canvasMeyveleriSayalim.Children.Add(IMG_meyve);
this.canvasMeyveleriSayalim.Children.Add(RectMeyve);
IMG_meyve.PointerPressed += IMG_meyve_PointerPressed;
IMG_meyve.PointerReleased += IMG_meyve_PointerReleased;
}
}
private void IMG_meyve_PointerPressed(object sender, PointerRoutedEventArgs e)
{
isHoldMeyve = true;
positionWithinImage = e.GetCurrentPoint(sender as Image).Position;
meyveX = e.GetCurrentPoint(IMG_meyve).Position.X;
meyveY = e.GetCurrentPoint(IMG_meyve).Position.Y;
}
private void canvasSayfa10_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (isHoldMeyve)
{
if (Convert.ToInt32(IMG_meyve.Tag) == pressedIMGTag) //this part useless
{
PointerPoint pt1 = e.GetCurrentPoint(canvasMeyveleriSayalim);
Canvas.SetLeft(IMG_meyve, pt1.Position.X - meyveX);
Canvas.SetTop(IMG_meyve, pt1.Position.Y - meyveY);
}
}
}
sorry for my english.
where is my mistake.

how to place my button?

I have a problem with my C# WinForm project.
In my project I have a function to draw a square, and I have a function that makes buttons at run time. What I want to do is that the button will place on the square.
I try to use 2 arrays; one gets the x location of the square, and the other gets the y location.
The button is placed at the x and y location one by one in columns but its place them diagonal.
int[] locationx = new int[100];
int[] locationy = new int[100];
int monex = 0;
int money = 0;
private void DrawAllSquares()//z,k its many square its going to draw
{
int tempy = y;
for (int i = 0; i < z; i++)
{
DrawingSquares(x, y);
for (int j = 0; j < k - 1; j++)
{
locationy[money] = tempy;
money++;
tempy += 60;
DrawingSquares(x, tempy);
}
x += 120;
locationx[monex] = x;
monex++;
tempy = y;
}
}
private void button2_Click(object sender, EventArgs e)
{
Button myText = new Button();
myText.Tag = counter;
//changeplace();
myText.Location = new Point(locationx[monex2], locationy[money2]);
monex2++;
money2++;
buttonList.AddLast(myText);
myText.Text = Convert.ToString(textBox3.Text);
this.Controls.Add(myText);
buttons[counter] = myText;
myText.BringToFront();
counter++;
}
You need do add created button to Form Controls collection.
private void button2_Click(object sender, EventArgs e)
{
Button myText = new Button();
myText.Tag = counter;
myText.Location = new Point(locationx[monex2], locationy[money2]);
Controls.Add(myText); // Assuming that handler 'button2_Click' is in your Form class.
// rest of your code
}
EDIT:
Button myText = new Button();
myText.Click += button2_Click;

How to add buttons dynamically to my form?

I want to create 10 buttons on my form when I click on button1. No error with this code below but it doesnt work either.
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < buttons.Capacity; i++)
{
this.Controls.Add(buttons[i]);
}
}
You aren't creating any buttons, you just have an empty list.
You can forget the list and just create the buttons in the loop.
private void button1_Click(object sender, EventArgs e)
{
int top = 50;
int left = 100;
for (int i = 0; i < 10; i++)
{
Button button = new Button();
button.Left = left;
button.Top = top;
this.Controls.Add(button);
top += button.Height + 2;
}
}
It doesn't work because the list is empty. Try this:
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < 10; i++)
{
Button newButton = new Button();
buttons.Add(newButton);
this.Controls.Add(newButton);
}
}
You could do something like this:
Point newLoc = new Point(5,5); // Set whatever you want for initial location
for(int i=0; i < 10; ++i)
{
Button b = new Button();
b.Size = new Size(10, 50);
b.Location = newLoc;
newLoc.Offset(0, b.Height + 5);
Controls.Add(b);
}
If you want them to layout in any sort of reasonable fashion it would be better to add them to one of the layout panels (i.e. FlowLayoutPanel) or to align them yourself.
Two problems- List is empty. You need to add some buttons to the list first. Second problem: You can't add buttons to "this". "This" is not referencing what you think, I think. Change this to reference a Panel for instance.
//Assume you have on your .aspx page:
<asp:Panel ID="Panel_Controls" runat="server"></asp:Panel>
private void button1_Click(object sender, EventArgs e)
{
List<Button> buttons = new List<Button>();
for (int i = 0; i < buttons.Capacity; i++)
{
Panel_Controls.Controls.Add(buttons[i]);
}
}
use button array like this.it will create 3 dynamic buttons bcoz h variable has value of 3
private void button1_Click(object sender, EventArgs e)
{
int h =3;
Button[] buttonArray = new Button[8];
for (int i = 0; i <= h-1; i++)
{
buttonArray[i] = new Button();
buttonArray[i].Size = new Size(20, 43);
buttonArray[i].Name= ""+i+"";
buttonArray[i].Click += button_Click;//function
buttonArray[i].Location = new Point(40, 20 + (i * 20));
panel1.Controls.Add(buttonArray[i]);
} }
I had the same doubt and came up with the following contribution:
int height = this.Size.Height;
int width = this.Size.Width;
int widthOffset = 10;
int heightOffset = 10;
int btnWidth = 100; // Button Widht
int btnHeight = 40; // Button Height
for (int i = 0; i < 50; ++i)
{
if ((widthOffset + btnWidth) >= width)
{
widthOffset = 10;
heightOffset = heightOffset + btnHeight
var button = new Button();
button.Size = new Size(btnWidth, btnHeight);
button.Name = "" + i + "";
button.Text = "" + i + "";
//button.Click += button_Click; // Button Click Event
button.Location = new Point(widthOffset, heightOffset);
Controls.Add(button);
widthOffset = widthOffset + (btnWidth);
}
else
{
var button = new Button();
button.Size = new Size(btnWidth, btnHeight);
button.Name = "" + i + "";
button.Text = "" + i + "";
//button.Click += button_Click; // Button Click Event
button.Location = new Point(widthOffset, heightOffset);
Controls.Add(button);
widthOffset = widthOffset + (btnWidth);
}
}
Expected Behaviour:
This will generate the buttons dinamically and using the current window size, "break a line" when the button exceeds the right margin of your window.
First, you aren't actually creating 10 buttons. Second, you need to set the location of each button, or they will appear on top of each other. This will do the trick:
for (int i = 0; i < 10; ++i)
{
var button = new Button();
button.Location = new Point(button.Width * i + 4, 0);
Controls.Add(button);
}
You can't add a Button to an empty list without creating a new instance of that Button.
You are missing the
Button newButton = new Button();
in your code plus get rid of the .Capacity

Categories