有一种方法可以使控件的背景透明winforms
(彼此重叠)。但是,在运行时移动控件可能会使其闪烁。另一种选择是使用Region
为您的控件指定区域,使其理论上具有任何形状。这是我能为你做的,只是一个演示:
public partial class VerticalArrow : UserControl
{
public VerticalArrow()
{
InitializeComponent();
Direction = ArrowDirection.Up;
}
public enum ArrowDirection
{
Up,
Down
}
ArrowDirection dir;
public ArrowDirection Direction
{
get { return dir; }
set
{
if (dir != value)
{
dir = value;
UpdateRegion();
}
}
}
//default values of ArrowWidth and ArrowHeight
int arrowWidth = 14;
int arrowHeight = 18;
public int ArrowWidth
{
get { return arrowWidth; }
set
{
if (arrowWidth != value)
{
arrowWidth = value;
UpdateRegion();
}
}
}
public int ArrowHeight
{
get { return arrowHeight; }
set
{
if (arrowHeight != value)
{
arrowHeight = value;
UpdateRegion();
}
}
}
//This will keep the size of the UserControl fixed at design time.
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, Math.Max(ArrowWidth, 4), height, specified);
}
private void UpdateRegion()
{
GraphicsPath gp = new GraphicsPath();
int dx = ArrowWidth / 2 - 1;
int dy = ArrowHeight / 2;
Point p1 = new Point(dx, Direction == ArrowDirection.Up ? dy : 1);
Point p2 = new Point(ArrowWidth - dx, Direction == ArrowDirection.Up ? dy + 1: 1);
Point p3 = new Point(ArrowWidth - dx, Direction == ArrowDirection.Up ? ClientSize.Height : ClientSize.Height - dy);
Point p4 = new Point(dx, Direction == ArrowDirection.Up ? ClientSize.Height : ClientSize.Height - dy);
Point q1 = Direction == ArrowDirection.Up ? new Point(0, ArrowHeight) : new Point(0, ClientSize.Height - ArrowHeight);
Point q2 = Direction == ArrowDirection.Up ? new Point(dx, 0) : new Point(dx, ClientSize.Height);
Point q3 = Direction == ArrowDirection.Up ? new Point(ArrowWidth, ArrowHeight) : new Point(ArrowWidth, ClientSize.Height - ArrowHeight);
if (Direction == ArrowDirection.Up) gp.AddPolygon(new Point[] { p1, q1, q2, q3, p2, p3, p4 });
else gp.AddPolygon(new Point[] {p1,p2,p3,q3,q2,q1,p4});
Region = new Region(gp);
}
protected override void OnSizeChanged(EventArgs e)
{
UpdateRegion();
base.OnSizeChanged(e);
}
}
结果如下:
您可以使用BackColor
更改箭头的颜色。如果我们只需要绘制箭头,代码会更简单,尤其是在属性和System.Drawing.Drawing2D.AdjustableArrowCap
处理的帮助下。但是,对于您的要求,在许多情况下使用几乎是最佳选择。CustomStartCap
CustomEndCap
Region
更新
如果您希望使用Background
我们使用的透明解决方案Pen
而CustomLineCap
不是裁剪Region
,则VerticalArrow
必须继承自Control
. 这是代码:
public class VerticalArrow : Control
{
public VerticalArrow()
{
Width = 30;
Height = 100;
Direction = ArrowDirection.Up;
ArrowHeight = 4;
ArrowWidth = 4;
TrunkWidth = 2;
SetStyle(ControlStyles.Opaque, true);
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
public ArrowDirection Direction { get; set; }
public int ArrowHeight { get; set; }
public int ArrowWidth { get; set; }
public int TrunkWidth { get; set; }
Point p1, p2;
public enum ArrowDirection
{
Up,
Down,
UpDown
}
protected override void OnSizeChanged(EventArgs e)
{
p1 = new Point(Width / 2, 0);
p2 = new Point(Width / 2, Height);
base.OnSizeChanged(e);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (Pen p = new Pen(ForeColor))
{
using (AdjustableArrowCap cap = new AdjustableArrowCap(ArrowWidth, ArrowHeight))
{
if (Direction == ArrowDirection.Up || Direction == ArrowDirection.UpDown) p.CustomStartCap = cap;
if (Direction == ArrowDirection.Down || Direction == ArrowDirection.UpDown) p.CustomEndCap = cap;
}
p.Width = TrunkWidth;
e.Graphics.DrawLine(p, p1, p2);
}
}
}
截屏:
要Arrow color
更改ForeColor
.