我正在尝试在表单中创建一些自定义按钮,理论上应该如下图所示:
我创建了自定义窗体控件类来制作每个按钮。它们是使用PictureBox实现的,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的矩形形状如下图所示,我仍无法纠正PictureBoxes相互重叠的问题:
我也知道在 Picturebox.Backcolor 属性中设置背景透明,会使背景对其父类透明。但是,因为,每个PictureBox与其他2个图片框以及表格部分重叠。怎么能成为可能呢?最有可能的情况是,使用PictureBox无法完成;但是用Label实现。我试图为此编码,但没有成功。如何实现点击和普通图像,以及通过标签解决它的 HitTest(PictureBox控件,int x,int y) 方法?如果有人能帮助我解决这个问题,或找到解决方法,我将非常感激。
答案 0 :(得分:1)
我可以通过覆盖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);
}
}
将控件添加到表单并确保其具有方形尺寸。它们看起来像是在设计师中重叠,但点击事件只会在三角区域内发射。