Click to See Complete Forum and Search --> : Pass Data onclick event


Theone2k
November 20th, 2009, 05:13 PM
Hi,

I have a form with a flow layout panel which I'm loading multiple images into


...
Image = new Bitmap(Picture);
AlbumImage = new PictureBox();
AlbumImage.Height = 75;
AlbumImage.Width = 100;
AlbumImage.SizeMode = PictureBoxSizeMode.StretchImage;
AlbumImage.Image = Image;

AlbumImage.Click += new EventHandler<string>(ImageClicked);

BackPanel.Controls.Add(AlbumImage);
...


now when i click an AlbumImage it fires ImageClicked ok but how would I pass an Image ID so i know which image has been clicked

Thanks

BigEd781
November 20th, 2009, 05:33 PM
First, your code will not compile. This line:

AlbumImage.Click += new EventHandler<string>(ImageClicked);


...is not valid. The argument to the generic EventHandler must be derived from EventArgs.

Now, what is "AlbumImage"? Is this your own class? If so, then you just need to create your own class derived from EventArgs which contains the information you need.

Theone2k
November 20th, 2009, 05:40 PM
Ah yeah i have taken the string out :)

AlbumImage is a standard PictureBox


AlbumImage = new PictureBox();

BigEd781
November 20th, 2009, 05:44 PM
Ah yeah i have taken the string out :)

AlbumImage is a standard PictureBox


AlbumImage = new PictureBox();


If it is a standard picture box then you can only display one image at a time. Even if you have sub images inside of that image, figuring out which was clicked in this way will be messy. I would suggest creating a UserControl which contains multiple pictureboxes. You can then pass the click event from any child control through the UserControl with some extra information in your custom EventArgs class.

Theone2k
November 20th, 2009, 05:50 PM
The Full load Code



Bitmap Image;
PictureBox AlbumImage = new PictureBox();
Label AlbumDescription;
FlowLayoutPanel BackPanel;

// Process the list of files found in the directory.
string[] Thumbnails = Directory.GetFiles("C:\\Users\\David\\Desktop\\Wedding Photos\\Thumbnails");
foreach (string Picture in Thumbnails)
{
// do something with fileName
BackPanel = new FlowLayoutPanel();
BackPanel.Height = 110;
BackPanel.Width = 110;
BackPanel.BackColor = Color.White;
BackPanel.Margin = new System.Windows.Forms.Padding(0);

Image = new Bitmap(Picture);
AlbumImage = new PictureBox();
AlbumImage.Height = 75;
AlbumImage.Width = 100;
AlbumImage.SizeMode = PictureBoxSizeMode.StretchImage;
AlbumImage.Image = Image;

AlbumImage.Click += new EventHandler(ImageClicked);

BackPanel.Controls.Add(AlbumImage);
AlbumDescription = new Label();
AlbumDescription.Text = "Album Description";
BackPanel.Controls.Add(AlbumDescription);


this.AlbumFlow.Controls.Add(BackPanel);
}

this.AlbumFlow.AutoSize = true;
this.MaskPanel.Controls.Add(AlbumFlow);
this.AlbumFlow.Location = this.MaskPanel.Location;

this.AlbumFlow.Left = this.AlbumFlow.Left += 17;

this.btn_Albumright.Location = this.MaskPanel.Location;
this.btn_AlbumLeft.Location = this.MaskPanel.Location;
this.btn_AlbumLeft.Top -= 1;
this.btn_Albumright.Top -= 1;
this.btn_AlbumLeft.Left = this.MaskPanel.Width - 10;

}


What happens is the program looks in a folder for all the images and loads then loops through loading each image into a new Picturebox this then gets added to a flowlayoutcontrol so i get a bar with all the images loaded.

what I'm trying to do is find out which image has been clicked So i can then load that albums images into the next part of the program...

BigEd781
November 20th, 2009, 06:00 PM
Yes, I know. You could so this by casting the 'sender' object to a picturebox and then saving a reference to its "Image" property. However, if you want to do this in a cleaner fashion I would still recommend the UserControl approach.

Theone2k
November 20th, 2009, 06:15 PM
Wouldn't I still have the same problem with a user control that i would have to cast the sender as the new user control?

BigEd781
November 20th, 2009, 06:21 PM
Wouldn't I still have the same problem with a user control that i would have to cast the sender as the new user control?

Nope. Your user control would contain some number of PictureBox controls. You would handle the click event for each PictureBox internally and then fire your own, custom event, something like "ImageClicked". Now you create your own event handler class. This class may contain a field named "Image" that contains a reference to the clicked image. So now you just handle the "ImageClicked" event in your form class and you automatically get information on the clicked image, you don't care about which control was clicked. This is a far more extensible and maintainable solution. You can easily modify your UserControl class without having to change all of the code in your form class. It is just a separation of concerns.

Theone2k
November 20th, 2009, 06:29 PM
Hmm I was thinking of making a user control for the thumbnail views (These Pics).

you also suggest it should contain a number of picture boxes and handle the clicks internally but I have a variable number of images...would i not get the same issue in the user control...

I have never made a user control before :)

BigEd781
November 20th, 2009, 06:37 PM
You would have to dynamically create and load the images then. Your UserControl would serve as a container, and for each child control that you add you would subscribe to its click event. Yes, you would still be casting sender to get the image, but that logic is now where it belongs instead of in your Form class.

Of course, if you wanted to avoid that as well you could also create your own class derived from PictureBox and add an "ImageClicked" event which passed the image along in the EventArgs parameter. Then you don't need to cast anything, but the cast isn't bad really.

Theone2k
November 20th, 2009, 08:01 PM
Thanks for the help

also found this site

http://ondotnet.com/pub/a/dotnet/2002/04/15/events.html?page=2

was relay helpful

I have made a Thumbnail User Control which I was planning to do eventually this now lets me send info via a custom events args that will give me the data i need and I don't need to cast anything :D