Events from controls created at run-time - c#

I am populating a flowLayoutPanel with pictureBoxes at run-time with the following code
for (int i = 0; i < immageArray.Length; i++)
{
Image image = Image.FromFile(immageArray[i]);
pictureBoxArray[i] = new PictureBox();
pictureBoxArray[i].Image = image;
pictureBoxArray[i].Width = 256;
pictureBoxArray[i].Height = 256;
pictureBoxArray[i].SizeMode = PictureBoxSizeMode.Zoom;
flowLayoutPanel1.Controls.Add(pictureBoxArray[i]);
}
How can do I create the event/events for controls that don't exist yet at design time?

Try this:
pictureBoxArray[i].MouseDown += new MouseEventHandler(pictureBox_MouseDown);
...
private void pictureBox_MouseDown(object sender, MouseEventArgs e)
{
....
}
pictureBox_MouseDown is your mouseDown event handler, of course you can attach any event not only MouseDown and you can do it for any control created at runtime.
here is the list of events for PictureBox

Related

How to dynamically add events to a large number of controls?

I'm trying to add 1152 small pictureBoxes to a Winform dynamically then I want to add to each of those pictureBoxes a Click event so that when I click on them, the image change. I have no idea how to add event handler!?
private void Form1_Load(object sender, EventArgs e)
{
Image image1= Image.FromFile(#"C:\Users\image1.png");
Image image2= Image.FromFile(#"C:\Users\image2.png");
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
var pictures= new PictureBox
{
Name = "pic" + i + j,
Size = new Size(14, 14),
Location = new Point(j * 14, i * 14),
Image = image1,
};
this.Controls.Add(pictures);
}
}
}
So you have a sequence of PictureBoxes and you want two things:
You want to subscribe to a Click event
If the Click event occurs you want to change the image, probably depending on the picture box that was clicked.
First you need to have a sequence of the PictureBoxes you want to have this behaviour. If you don't have a sequence yet, and you want all PictureBoxes on a certain Control to have this behaviour you could use this:
IEnumerable<PictureBox> GetPictureBoxes(Control control)
{
return control.Controls.OfType<PictureControl>();
}
See Enumerable.OfType
Subscribe to event:
IEnumerable<PictureBox> myPictureBoxes = ...
foreach (PictureBox pictureBox in myPictureBoxes)
{
pictureBox.Click += new System.EventHandler(this.pictureBox_Click);
}
Event handler:
private void pictureBox1_Click(object sender, EventArgs e)
{
PictureBox pictureBox = (PictureBox)sender;
Image imageToShow = DecideWhichImageToShow(pictureBox); // TODO
// change the image:
pictureBox.Image = imageToShow
}
On event handler's method, the sender argument will be your PictureBox object, so you can write something like this:
private void Pb_Click(object sender, EventArgs e)
{
PictureBox pb = sender as PictureBox;
try
{
if (pb != null)
pb.Image = Image.FromFile(#"NewImagePath");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

WinForm Button Event Handler (Dynamic)

I'd like to distinguish each of the Event handler.
(I have only one in my code below. I mean dynamic handler will be the best but, any kind of workarounds will be fine too.)
Please help me.
Thanks !
List<Button> VuttonList = new List<Button>();
private void Form1_Load(object sender, EventArgs e)
{
Button Vutton;
int Kount = 10;
for (int i = 0; i < Kount ; i++)
{
Vutton = new Button();
Vutton.Text = ( i + 1 ).ToString() ;
Vutton.Location = new Point(10, 24 * ( i + 1 ) );
Controls.Add( Vutton );
Vutton.Click += new EventHandler(Kommon);
VuttonList.Add( Vutton );
}
}
private void Kommon(object sender, EventArgs e)
{
MessageBox.Show( sender.ToString() );
}
One event handler is enough, you can cast the sender to Button and this way you know which button has been clicked. Also you can set Name property of buttons when you create them or assign Tag property of them and use it later.
for (int i = 0; i < Kount ; i++)
{
Vutton = new Button();
//...set properties
//Also add Name:
Vutton.Name = string.Format("Vutton{0}", i);
//Also you can add Tag
Vutton.Tag = i;
Controls.Add( Vutton );
Vutton.Click += new EventHandler(Kommon);
//... other stuff
}
Then you can use properties of button this way:
private void Kommon(object sender, EventArgs e)
{
var button = sender as Button;
//You can use button.Name or (int)button.Tag and ...
MessageBox.Show(button.Name);
}
Also to layout your buttons, you can use a FlowLayoutPanel or a TableLayoutPanel.

I created an array of pictureBoxes how can i register for an event to all the pictureBoxes?

The code:
pbs = new PictureBox[8];
for (int i = 0; i < pbs.Length; i++)
{
pbs[i] = new PictureBox();
pbs[i].MouseEnter += Form1_MouseEnter;
pbs[i].MouseLeave += Form1_MouseLeave;
pbs[i].Size = new Size(100, 100);
pbs[i].Margin = new Padding(0, 0, 0, 60);
pbs[i].Dock = DockStyle.Top;
pbs[i].SizeMode = PictureBoxSizeMode.StretchImage;
Panel p = i < 4 ? panel1 : panel2;
p.Controls.Add(pbs[i]);
pbs[i].BringToFront();
}
I did:
pbs[i].MouseEnter +=
And when i clicked TAB it did: Form1_MouseEnter
It's not what i wanted.
I want that when i move with the mouse over each of the pictureBoxes area it will do something.
One event for all the pictureBoxes.
If i moved over pictureBox1 do something...pictureBox2 the same...
How can i do it ? I don't want to create 8 events for each pictureBox but one enter event for all.
You need simply write
pbs[i].MouseEnter += globalMouseEnterEvent;
of course you need to have a globalMouseEnterEvent somewhere in your code
public void globalMouseEnterEvent(object sender, System.EventArgs e)
{
....
}
However, another piece of information is needed when your work with event shared between numerous controls. You need to recognize the control that triggers the event. The control instance is passed using the sender parameter that you can cast to your appropriate control type, but what is needed is to give a unique identifier to your control. Like setting the Tag or Name properties when you build the control
for (int i = 0; i < pbs.Length; i++)
{
.....
pbs[i].Tag = "PB" + i.ToString()
...
}
so in the MouseEnter code you could write
public void globalMouseEnterEvent(object sender, System.EventArgs e)
{
PictureBox p = sender as PictureBox;
if(p.Tag.ToString() == "PB1")
.....
else if ......
}
dont use form1_event , copy it's code and rename it
pbs[i].MouseEnter += yourEventName
it's enough
What you're doing is absolute correct, you attach the handler to the event of each control in
turn, so that the same handler works for every PictureBox.
I guess your problem is that the method VS creates is named Form1_MouseEnter. This is completely irrelevant, what determines what a method will handle is the += operator, not its name. Just try to run your original code and it will do what you want.
It seems to be a bug in the C# editor though, as it should have named the automatically generated handler something more appropriate, but anyway, you can rename the method afterwards to reflect its true meaning.
I've tried to apply the tips from the others to your code:
pbs = new PictureBox[8];
for (int i = 0; i < pbs.Length; i++)
{
pbs[i] = new PictureBox();
pbs[i].MouseEnter += Picturebox_MouseEnter;
pbs[i].MouseLeave += PictureBox_MouseLeave;
pbs[i].Name = string.Concat("PB", i); //Added to identify each picturebox
pbs[i].Size = new Size(100, 100);
pbs[i].Margin = new Padding(0, 0, 0, 60);
pbs[i].Dock = DockStyle.Top;
pbs[i].SizeMode = PictureBoxSizeMode.StretchImage;
Panel p = i < 4 ? panel1 : panel2;
p.Controls.Add(pbs[i]);
pbs[i].BringToFront();
}
And the handlers:
private void Picturebox_MouseEnter(object sender, EventArgs e)
{
PictureBox pb = sender as PictureBox;
if (pb != null)
{
if (pb.Name == "PB2")
{
//Do PB2 specific task
}
//Your code when mouse enters one of the pictureboxes
//Use Name property to determine wich one, if needed
}
}
private void PictureBox_MouseLeave(object sender, EventArgs e)
{
//Your code when mouse leaves one of the pictureboxes
//Use Name property to determine wich one, if needed
}

Click event for dynamically created array of buttons

In my application i have array of buttons created dynamically.I am trying to raise an onclick event for those buttons and change the text of the button which i click.I tried the below code for this but its not working.How can i do this?.Any suggesions?
Code:
for (int i = 0; i < 5; i++)
{
lbl = new Button[5];
lbl[i] = new Button();
lbl[i].Text = "hi";
lbl[i].Width = 30;
lbl[i].Click += new EventHandler(lbl_click);
//lbl[i].CssClass = "label";
div1.Controls.Add(lbl[i]);
}
Click Event:
protected void lbl_click(object sender, EventArgs e)
{
Button[] lbl = sender as button[];
lbl[i].Text = "clicked";
}
You are recreating the array of buttons in your event handler, but this array is not populated with the buttons created before. It is empty and will give you a null reference exception if you try to use an element of this array (null.Text, it will never work).
The sender object instead, represent the button that the user has clicked.
protected void lbl_click(object sender, EventArgs e)
{
Button lbl = sender as Button;
lbl.Text = "clicked";
}
Also, if you need to know which specific button has been clicked then I suggest you to add something to differentiate between them at creation time:
For example use the name property:
Button[] lbl = new Button[5];
for(int i = 0; i< 5; i++)
{
....
lbl[i].Name = "Button_" + i.ToString();
....
}
Notice that I have moved the array declaration and initialization outside the loop that create every single element of the array (the actual button).

How create processing events for array of TextBox

I create array:
TextBox[] textarray = new TextBox[100];
Then in cycle set this params, all items array situated in uniformGrid1
textarray[i] = new TextBox();
textarray[i].Height = 30;
textarray[i].Width = 50;
uniformGrid1.Children.Add(textarray[i]);
How create events Click or DoubleClick that all items array?
Sorry my English.
public static void blah()
{
TextBox[] textarray = new TextBox[100];
List<TextBox> textBoxList = new List<TextBox>();
for (int i = 0; i < textarray.Length; i++)
{
textarray[i] = new TextBox();
textarray[i].Height = 30;
textarray[i].Width = 50;
// events registration
textarray[i].Click +=
new EventHandler(TextBoxFromArray_Click);
textarray[i].DoubleClick +=
new EventHandler(TextBoxFromArray_DoubleClick);
}
}
static void TextBoxFromArray_Click(object sender, EventArgs e)
{
// implement Event OnClick Here
}
static void TextBoxFromArray_DoubleClick(object sender, EventArgs e)
{
// implement Event OnDoubleClick Here
}
EDIT:
A better / recommended way of event registration as per #Aaronaugh: advice:
textarray[i].Click += TextBoxFromArray_Click;
textarray[i].DoubleClick += TextBoxFromArray_DoubleClick;
Just add in your click or double click event handler. For example, to trap double click events:
textarray[i] = new TextBox();
textarray[i].Height = 30;
textarray[i].Width = 50;
textarray[i].MouseDoubleClick += this.OnMouseDoubleClick;
uniformGrid1.Children.Add(textarray[i]);
For the above to work, you class will need a method like:
void OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
// Do something
}
Create a click event handler and then use it to subscribe to the click events of your textboxes, like so:
textarray[i].Click += new EventHandler(textbox_Click);
...
void textbox_Click(object sender, EventArgs e)
{
// do something
}
If the actions you want to take are the same for each textbox, then one click handler will suffice.

Categories

Resources