PictureBox - Handle Click Event on Non-Transparent Area of Image

后端 未结 2 1705
难免孤独
难免孤独 2021-01-14 19:59

I have to make a windows form in C# where two PictureBox are overlapping. TopPictureBox is containing a transparent png picture. By default TopPictureBox can be clicked by c

2条回答
  •  轻奢々
    轻奢々 (楼主)
    2021-01-14 20:33

    Checking if a position in PictureBox is Transparent or not depends on the Image and SizeMode property of PictureBox.

    You can not simply use GetPixel of Bitmap because the image location and size is different based on SizeMode. You should first detect the size and location of Image based on 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;
    }
    

    Then you can simply use HitTest method to check if the mouse is over a non-transparent area of 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");
    }
    

    Also setting BackColor to Color.Transparent only makes the PictureBox transparent relative to it's parent. For example if you have 2 PictureBox in a Form setting the transparent back color, just cause you see the background of form. To make a PictureBox which supports transparent background, you should draw what is behind the control yourself. You can find a TransparentPictureBox in this post: How to make two transparent layer with c#?

提交回复
热议问题