Title: Improve the picture list in C#
My post Make a picture list in C# explained how you can make a picture list that lets the user add, remove, and rearrange pictures. This post adds a small improvement.
The previous example displayed images in PictureBox controls with BorderStyle set to None. Unfortunately, if you set the BorderStyle to something else, then the context menu did not line up properly when you right-clicked on one of those controls. When you pressed and released the mouse, the context menu jumped slightly. This wasn't a big deal, but it was annoying so I made that example use borderless PictureBox controls for its picture list.
The following code snippet shows how the previous example calculated the mouse's position in panPictures coordinates.
// Display the context menu.
PictureBox pic = sender as PictureBox;
ShowContextMenu(new Point(pic.Left + e.X, pic.Top + e.Y));
This code adds the PictureBox control's upper left corner coordinates to the mouse's coordinates in that control's coordinate system. In other words, it starts at the control's upper left corner and then adds the coordinates of the mouse within the control to get the control's position relative to the panPictures parent control.
The problem is that the coordinates reported by the PictureBox are relative to that control's client area, and that area does not include the control's border. That means the mouse's location is off by the thickness of the control's left and top borders.
There doesn't seem to be a way to find the thickness of a control's border directly, so you can't just add it into the calculation. Fortunately, you can convert a point from the coordinate system of one control to that of another. The new example does that in the following snippet.
PictureBox pic = sender as PictureBox;
// Get the mouse's location in panPictures coordinates.
Point screen_point = pic.PointToScreen(e.Location);
Point parent_point = panPictures.PointToClient(screen_point);
// Display the context menu.
ShowContextMenu(new Point(
parent_point.X,
parent_point.Y));
This code calls the PictureBox control's PointToScreen method to convert the mouse's location to screen coordinates. That gives the mouse's position relative to the screen's upper left corner. The code then calls the panPictures control's PointToClient method to convert the screen coordinates into the panPictures control's coordinate system.
This is actually a more direct way to calculate the mouse's position, and it also works no matter what border style you give to the PictureBox controls used by the picture list.
In my next post, I'll add another enhancement that will force a redesign of much of the program.
Download the example to experiment with it and to see additional details.
|