c# - PictureBox - 处理图像非透明区域的点击事件

标签 c# .net winforms transparency picturebox

我必须在 C# 中制作一个窗口窗体,其中两个 PictureBox 重叠。 TopPictureBox 包含一张透明的 png 图片。默认情况下,可以通过单击 TopPictureBox 中图像的任何可见或透明区域来单击 TopPictureBox。但我想让 TopPictureBox 只能通过单击图像的可见区域来单击,而不是在透明区域中单击。另外我想让光标仅在图像的可见区域发生变化,而不是在透明区域发生变化。

有什么办法可以做到这些吗?

我正在使用此代码使 TopPictureBox 透明。

TopPictureBox.BackColor = Color.Transparent;

感谢您的帮助。

enter image description here

最佳答案

检查位置是否在 PictureBox 中是 Transparent或不取决于 ImageSizeMode PictureBox的属性(property).

您不能简单地使用GetPixelBitmap因为图像位置和大小根据 SizeMode 不同。您应该首先检测Image的大小和位置。基于SizeMode :

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 - r.X, y - r.Y).A != 0)
            result = true;
    }
    return result;
}

然后你可以简单地使用HitTest检查鼠标是否位于 PictureBox 的非透明区域上的方法:

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (HitTest(pictureBox1,e.X, e.Y))
        pictureBox1.Cursor = Cursors.Hand;
    else
        pictureBox1.Cursor = Cursors.Default;
}

private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
    if (HitTest(pictureBox1, e.X, e.Y))
        MessageBox.Show("Clicked on Image");
}

同时设置BackColorColor.Transparent只使得PictureBox相对于它的父级是透明的。例如,如果您有 2 PictureBoxForm设置透明背景颜色,只是为了让你看到表单的背景。制作 PictureBox它支持透明背景,您应该自己绘制控件后面的内容。您可以找到TransparentPictureBox在这篇文章中:How to make two transparent layer with c#?

关于c# - PictureBox - 处理图像非透明区域的点击事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38965660/

相关文章:

c# - 实时、迭代应用架构

c# - C# 中的后期评估?

.net - 是否推荐使用函数式编程 (F#) 实现时间序列?

c# - 动态更改 log4net 连接字符串

.net - WinForms 4K 和 1080p 缩放/高 DPI?

c# - 为什么 Windows 窗体应用程序中的窗体类被声明为部分的?

c# - 启用调整 Windows Forms 窗体的大小

c# - c# 中有 lorem ipsum 生成器吗?

c# - 编程 float 运动

c# - 属性信息 : is the property an indexer?