gpt4 book ai didi

c# - 如何防止多张图片相互重叠

转载 作者:行者123 更新时间:2023-11-30 17:30:42 32 4
gpt4 key购买 nike

我正在尝试在表单中制作一些自定义按钮,理论上应该如下图所示:

Buttons

我创建了自定义窗口窗体控件类来制作每个按钮。它们是使用 PictureBox 实现的,它包含一个用于单击状态的图像和另一个用于未单击状态的图像。该类的代码如下:

public partial class MyCustomButton: PictureBox
{
public MyCustomButton()
{
InitializeComponent();

}

//variables
private Image NormalImage;
private Image ClickedImage;

//public properties
public Image ImangeNormal
{
get { return NormalImage; }
set { NormalImage = value; }
}
public Image ImageClicked
{
get { return ClickedImage; }
set { ClickedImage = value; }
}

//Button event properties implementation
private void MyCustomButton_MouseDown(object sender, MouseEventArgs e)
{
if (HitTest(this, e.X, e.Y))
this.Image = ClickedImage;

}

private void MyCustomButton_MouseUp(object sender, MouseEventArgs e)
{
if (HitTest(this, e.X, e.Y))
this.Image = NormalImage;
}

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

//Test if the mouse is over the 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 - r.X, y - r.Y).A != 0)
result = true;
}
return result;
}
}

正如您在上面的类中看到的,它测试鼠标是否在实际图像上而不是 PictureBox 的背景上;并且只有在实际图像上单击时,单击的图像才可见。但我仍然无法解决 PictureBox 相互重叠的问题,因为 PictureBox 的形状是矩形,如下图所示:

Overlapping Buttons

我还知道在 Picturebox.Backcolor 属性中设置背景透明会使背景对其父类透明。但是因为,每个 PictureBox 都与其他 2 个 Picture Box 以及表单有部分重叠。如何做到这一点?最有可能的情况是,它不能用 PictureBox 来完成;但使用标签实现。我试图为此编写代码,但没有成功。如何通过标签实现点击图像和普通图像,以及HitTest(PictureBox control, int x, int y) 方法解决它?如果有人能帮我解决这个问题,或者找到解决方法,我将不胜感激。

最佳答案

我能够通过覆盖 OnPaint 事件来绘制三角形然后将 Region 设置为同一区域来制作一个简单的三角形按钮。

我没有花时间使控件可旋转,它被涂成灰色只是为了说明。我已经评论了需要更改以支持这些内容的代码要点。

class ArrowButton : Button
{
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
float h = this.Height;
float w = this.Width;

// This defines the shape of the triangle
// This is an upwards pointing triangle
PointF[] pts = new PointF[] { new PointF(w / 2, 0), new PointF(0, w), new PointF(w, h) };

// This points down
//PointF[] pts = new PointF[] { new PointF(0, 0), new PointF(w, 0), new PointF(w / 2, h) };

// Paints the triangle a grey colour
g.FillPolygon(Brushes.Gray, pts);

GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
this.Region = new Region(gp);
}
}

将控件添加到窗体并确保它具有方形尺寸。它们在设计器中看起来像是重叠的,但点击事件只会在三角形区域内触发。

关于c# - 如何防止多张图片相互重叠,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49191438/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com