Making a slideshow viewer, handling events fired from arbitrary controls - c#

I am extending an image viewer to support slideshow functionality. I have used a split container to separate the main form into two panels.
Panel on the left will contain a list of thumbnails
Panel on the right will contain the full-size image
Each panel supports drag and drop. When I drop an image file into the thumbs panel, it should create a thumbnail and display it on the panel, starting from the top and working its way down as more images are dropped. By default, the first image available will be shown on the panel to the right.
When I select another thumbnail, the viewer will display the full-size image.
What is a good way to implement this list of thumbnails? I've looked through the list of controls available but can't decide which one is most appropriate for this.
I was thinking of dynamically creating PictureBox objects, but then it didn't seem obvious how after I register a Click event, how I would identify which PictureBox the event was sent from.
I am looking for one of two possible types of answers
going ahead with the PictureBox creation idea, but understanding how I should be handling the Click events to correctly show the desired image.
an alternative suggestion for displaying the list of thumbs (if the PictureBox idea is not feasible)

You can tie the event handler to multiply controls and identify them by the "sender" parameter. It always points to the event sender.
void OnClick(object sender, KeyEventArgs e) {
PictureEdit editor = (PictureEdit)sender;
}
Sub OnClick(ByVal sender As Object, ByVal e As KeyEventArgs)
Dim editor as PictureEdit = CType(sender, PictureEdit)
End Sub
Alternatively, you can create your own (not that complex) control divided into rectangular areas displaying images.

Related

clipping rectangle form winform as image [duplicate]

Suppose there is a picturexox on the panel
and there is a datagridview on the picturebox.
I use the following code to capture the panel:
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(panel1.ClientRectangle.Width, panel1.ClientRectangle.Height);
panel1.DrawToBitmap(bmp, panel1.ClientRectangle);
bmp.Save(#"test.jpg");
But it seems that only the picturebox has been captured, the datagridview on it is missing.
How can capture the picturebox together with the datagridview?
The DrawToBitmap method will capture the graphics drawn in the Paint event and all nested controls. If one is missing it isn't nested either directly of indirectly. Here is how this probably happened:
The designer behaviour of Panels and PictureBoxes is different.
Panels, like GroupBoxes, TabPages and a few more are container controls.
This means that any control you drag onto them with your mouse gets nested in them.
PictureBox is not a Container, like, say a Button or a Label..
To nest your DataGridView in the PictureBox you have a choice of
moving it there with the keyboard (!)
nesting it in code ( yourDGV.Parent = yourPBox1;)
Do test the success of the keyboard way by moving the PictureBox to see if the DGV moves with it..
Update:
If you nest the DGV in the PictureBox, which itself is nested in the Panel, all will be well and the result will looks just like what you see.
However, if you nest both DGV and PictureBox in the Panel and merely let them overlap, a strange bug will appear: Multiple overlapping controls are drawn in reverse, See here for a post and a link about this issue, which is documented
Controls inside containers are rendered in reverse order.
but obviously still a bug.

How to capture all the items inside a control?

Suppose there is a picturexox on the panel
and there is a datagridview on the picturebox.
I use the following code to capture the panel:
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(panel1.ClientRectangle.Width, panel1.ClientRectangle.Height);
panel1.DrawToBitmap(bmp, panel1.ClientRectangle);
bmp.Save(#"test.jpg");
But it seems that only the picturebox has been captured, the datagridview on it is missing.
How can capture the picturebox together with the datagridview?
The DrawToBitmap method will capture the graphics drawn in the Paint event and all nested controls. If one is missing it isn't nested either directly of indirectly. Here is how this probably happened:
The designer behaviour of Panels and PictureBoxes is different.
Panels, like GroupBoxes, TabPages and a few more are container controls.
This means that any control you drag onto them with your mouse gets nested in them.
PictureBox is not a Container, like, say a Button or a Label..
To nest your DataGridView in the PictureBox you have a choice of
moving it there with the keyboard (!)
nesting it in code ( yourDGV.Parent = yourPBox1;)
Do test the success of the keyboard way by moving the PictureBox to see if the DGV moves with it..
Update:
If you nest the DGV in the PictureBox, which itself is nested in the Panel, all will be well and the result will looks just like what you see.
However, if you nest both DGV and PictureBox in the Panel and merely let them overlap, a strange bug will appear: Multiple overlapping controls are drawn in reverse, See here for a post and a link about this issue, which is documented
Controls inside containers are rendered in reverse order.
but obviously still a bug.

Implementing a clickable map for an arbitrary image

I have a C# WPF application where I have several possible images, some having irregular shapes within the image. I would like to generate different events when clicking on the different shapes within the image.
For example: If the image was of the front of the house, I would genereate different events when clicking on the doorknob, the door, the windows, the roof, etc.
The image has to be resizable.
I can do it manually with a grid and shapes, but it seems like there should be a more elegant way.
I thought I saw a technique where you could make a "shadow" image that was like the original, but with each clickable region filled in a different color. (A "color map" of the clickable regions.) Then the click handler could access the color of the shadow image and raise the appropriate event. However, I couldn't figure out how to hide the shadow image "under" the display image and still have the click event handler pick up the color.
I'm sure there's a good way to handle this, I just don't normally work with images so I'm completely ignorant of it.
Thanks.
How about having the nice image higher in the Z-order than the "shadow image" and setting topImage.IsHitTestVisible = false;
This would cause clicks to bypass the top, visible image and go straight to the underlying shadow image click handler.
Another technique I have used in production code is to derive a new class from Image and override HitTestCore and test the pixel value myself and if it's a certain color or opacity, I return a different object. This way I control all the action.

C# Only refresh PictureBox/Panel when tell them to refresh?

I'm making a bomberman game in a C# windows form application. It has over 300 pictureboxes (walls) that are placed on a panel. The picturebox of bomberman himself is also on that panel.
When the location of bombermans picturebox changes, all the controls on the panel are automatically refreshed. Because there are so many controls on that panel, and because the location of the picturebox changes multiple times per second, the program becomes laggy when I try to move.
I want to have control over the refresh event of the panel (and it's controls), because I think my problem is solved when only the pictureboxes that need to be refreshed, are refreshed programmatically.
I hope someone can help me out with this!
Ruud.
If you move the child, the parent has to be refreshed because it may need to draw the area where child was located previously. It would also mean that all children (of parent) would get refreshed.
OTH, using so many controls may not be a good idea. I would suggest you to keep data structures describing walls and then use it to draw it within Panel (or your custom control). You can write your own logic for hit testing (mouse or keyboard click within wall boundary) by capturing mouse/keyboard events at Panel/Parent level. With correct organization data structure, hit testing can be very efficient.
You are trying to paint the whole form which will surely take time . If you want to change only a part of the form, which in your case is Moving the bomberman to a new position, Only invalidate the area you want to repaint and then pass it to the Invalidate method.
Do something similar to this.
//Invalidate previous position of bomberman
Rectangle invalid = new Rectangle(picturebox1.Location.x,picturebox1.Location.y,picturebox1.Width,picturebox1.Height);
Invalidate(invalid);
//Add code to move your picture box and then call above two lines again
invalid = new Rectangle(picturebox1.Location.x,picturebox1.Location.y,picturebox1.Width,picturebox1.Height);
Invalidate(invalid);
Note sure but somthing similar polished code would work...
Here is a link to an example for reference. http://msdn.microsoft.com/en-us/library/ms229628.aspx

Showing thumbnail of selected images in a desktop application using C Sharp

I have a desktop application in C sharp, in which I have to show selected images in thumbnail view ( the view will be some thing like the attached image). The selected image can be deselected using x (cross) button shown on image top. Can someone suggest me how this can be accomplished. I have seen this accomplished in ASP .net. But I have to accomplish this in C#. Any clue will be greatly welcomed.
Regards,
You can generate the thumbnails from the Image class in .Net (Image.GetThumbnailImage). As far as the layout you are showing here, you could use a FlowLayoutPanel, or some other type of panel (or roll your own) that would dynamically add the images to your form. From there you can highlight around the image and add your X control button in the OnPaint, just keep track of which are selected and which aren't via some container class (add the images to something like a HashSet (.Net 3.5 or higher) so that you can quickly add/remove them from the collection, and iterate it in the OnPaint.
My advise will be to create a custom control (or user control) that will encapsulate image thumbnail & its name. It will highlight & show cross when focused/hovered. Cross can be as simple as another image overlaid on thumbnail (showing/hiding in mouse over event). Then you just needs to create and lay out multiple instances of control in whatever manner you want.

Categories