コントロールの背景を透明にする方法がありますwinforms
(互いに重なり合って)。ただし、実行時にコントロールを移動すると、ちらつくことがあります。もう 1 つの選択肢は、 を使用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
は、多くの場合、を使用することがほぼ最良の選択です。
アップデート
クリッピングの代わりにandを使用するトランスペアレントを使用したソリューションが必要な場合は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
ます。