Title: Make shaped PictureBoxes in C#
This example shows how to use regions to make shaped PictureBoxes.
The PNG image format allows you to define transparent pixels. As you might guess, if you draw an image with transparent pixels, those pixels are not drawn and whatever lies below them shows through. The example program demonstrates this on the left side of its form. The program uses the following Paint event handler to draw two overlapping volleyball images that contain transparent pixels.
// Draw two overlapping images.
private void Form1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(Properties.Resources.Volleyball, 12, 25);
e.Graphics.DrawImage(Properties.Resources.Volleyball, 52, 65);
}
Unfortunately PictureBox controls do not have truly transparent backgrounds. If you display an image that has transparent pixels in a PictureBox, the PictureBox's background color shows through. If you set the PictureBox's BackColor property to Transparent, then the control shows whatever is on the surface of its container--the Form, GroupBox, Panel, or other container that holds the PictureBox. That works quite well unless the PictureBox overlaps some other control.
In this example, the PictureBoxes in the middle of the form overlap each other. Where the upper PictureBox overlaps the lower one it draws the form's background image instead of allowing parts of the lower PictureBox to show through.
Another problem with PictureBox controls is that they process mouse and other events even over their transparent pixels. In this example the four PictureBox controls all use the Hand cursor. You can see in the picture that the lower middle PictureBox is displaying the hand cursor even though the mouse is over that control's transparent pixels.
You can solve both of these problems (not showing things below the control and processing mouse events even for transparent pixels) by using shaped PictureBoxes. To do that you set the PictureBox control's Region property to restrict it to the non-transparent pixels.
This example uses the following code to make two shaped PictureBoxes on the right of its form.
// Restrict pictureBox3 and pictureBox4 to a circular region.
private void Form1_Load(object sender, EventArgs e)
{
// Make a Rectangle that defines the circular area.
Rectangle rect = new Rectangle(7, 4, 90 - 7, 87 - 4);
// Make a GraphicsPath and add the circle.
GraphicsPath path = new GraphicsPath();
path.AddEllipse(rect);
// Convert the GraphicsPath into a Region.
Region region = new Region(path);
// Restrict the PictureBoxes to the Region.
pictureBox3.Region = region;
pictureBox4.Region = region;
}
The code first makes a Rectangle that defines the area containing the non-transparent pixels. It creates a GraphicsPath object and adds an ellipse defined by the Rectangle to it. It then uses the GraphicsPath to define a Region. Finally it sets the PictureBox controls' Region properties to the Region.
Restricting a PictureBox to a region makes it not draw anything outside of the Region. In this example the PictureBox controls on the right don't need to show parts of the form that lie below the transparent pixels because the controls don't exist in those places. In fact, this example would work even if those images did not contain transparent pixels. The parts of the images outside of the Region simply aren't drawn.
The PictureBox controls also don't receive mouse events for the areas outside of the Region. In this example, the PictureBoxes on the right only display the hand cursor when the mouse is over their regions. Similarly all four PictureBox controls display a MessageBox when you click them, and the PictureBoxes on the right don't raise their Click events if you click outside of their regions.
Download the example to experiment with it and to see additional details.
|