PictureBox – 处理图像非透明区域上的点击事件
我必须在C#中创建一个窗体,其中两个PictureBox重叠。 TopPictureBox包含一个透明的png图片。 默认情况下,可以通过单击TopPictureBox中图像的任何可见或透明区域来单击TopPictureBox。 但是我想通过单击图像的可见区域而不是透明区域来单击TopPictureBox。 另外我想让光标只在图像的可见区域上改变,而不是在透明区域。
这有什么办法吗?
我正在使用此代码使TopPictureBox透明。
TopPictureBox.BackColor = Color.Transparent;
谢谢你的帮助。
检查PictureBox
的位置是否Transparent
取决于PictureBox
的Image
和SizeMode
属性。
您不能简单地使用Bitmap
GetPixel
,因为基于SizeMode
的图像位置和大小是不同的。 您应该首先根据SizeMode
检测Image
的大小和位置:
public bool HitTest(PictureBox control, int x, int y) { var result = false; if (control.Image == null) return result; var method = typeof(PictureBox).GetMethod("ImageRectangleFromSizeMode", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); var r = (Rectangle)method.Invoke(control, new object[] { control.SizeMode }); using (var bm = new Bitmap(r.Width, r.Height)) { using (var g = Graphics.FromImage(bm)) g.DrawImage(control.Image, 0, 0, r.Width, r.Height); if (r.Contains(x, y) && bm.GetPixel(x - rX, y - rY).A != 0) result = true; } return result; }
然后你可以简单地使用HitTest
方法来检查鼠标是否在PictureBox
的非透明区域上:
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) { if (HitTest(pictureBox1,eX, eY)) pictureBox1.Cursor = Cursors.Hand; else pictureBox1.Cursor = Cursors.Default; } private void pictureBox1_MouseClick(object sender, MouseEventArgs e) { if (HitTest(pictureBox1, eX, eY)) MessageBox.Show("Clicked on Image"); }
将BackColor
设置为Color.Transparent
只会使PictureBox
相对于它的父级透明。 例如,如果在Form
有2个PictureBox
设置透明背面颜色,则只需要看到窗体的背景。 要制作支持透明背景的PictureBox
,您应该自己绘制控件背后的内容。 你可以在这篇文章中找到一个TransparentPictureBox
: 如何使用c#创建两个透明层?
一种方法是检查用户单击的像素的颜色是否与表单的背景颜色相同。 如果是,则用户单击透明区域。
(注意:正如Reza所提到的,此代码只能在没有重叠PictureBox的情况下使用,即仅当图像的透明区域与Form的背景颜色相同时)
Color pixelColour; private void myPicturebox_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { pixelColour = ((Bitmap)myPicturebox.Image).GetPixel(point.X, point.Y); if (this.BackColor == pixelColour) { // User clicked on transparent area } else { // User clicked on image } } }