我想用馅饼的形式创建一个自己的Control,而不是像之后的图片中的尖端。我只是不知道如何使这个工作。
http://www.directupload.net/file/d/3563/a3hvpodw_png.htm
//编辑:
好的,我忘了提到我想在之后填写它。所以,如果我是对的,我需要一个区域,但我不知道该怎么做。说实话,到目前为止我没有考虑过你的想法。我到目前为止只使用了一个Pie,就像这样:
Graphics gfx = pe.Graphics;
Pen p = new Pen(Color.Red);
gfx.DrawPie(p, 0, 0, 200, 200, 0, 45);
base.OnPaint(pe);
这是我第一次使用自定义控件,很抱歉,如果我要问的是有点傻。
答案 0 :(得分:0)
试试这个:
class ShapedControl : Control
{
private float startAngle;
private float sweepAngle;
private float innerRadius;
private float outerRadius;
public ShapedControl()
{
InnerRadius = 30;
OuterRadius = 60;
StartAngle = 0;
SweepAngle = 360;
}
[DefaultValue(0)]
[Description("The starting angle for the pie section, measured in degrees clockwise from the X-axis.")]
public float StartAngle
{
get { return startAngle; }
set
{
startAngle = value;
Invalidate();
}
}
[DefaultValue(360)]
[Description("The angle between StartAngle and the end of the pie section, measured in degrees clockwise from the X-axis.")]
public float SweepAngle
{
get { return sweepAngle; }
set
{
sweepAngle = value;
Invalidate();
}
}
[DefaultValue(20)]
[Description("Inner radius of the excluded inner area of the pie")]
public float InnerRadius
{
get { return innerRadius; }
set
{
innerRadius = value;
Invalidate();
}
}
[DefaultValue(30)]
[Description("Outer radius of the pie")]
public float OuterRadius
{
get { return outerRadius; }
set
{
outerRadius = value;
Invalidate();
}
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
g.Clear(this.BackColor);
GraphicsPath gp1 = new GraphicsPath();
GraphicsPath gp2 = new GraphicsPath();
float xInnerPos = -innerRadius / 2f + this.Width / 2f;
float yInnerPos = -innerRadius / 2f + this.Height / 2f;
float xOuterPos = -outerRadius / 2f + this.Width / 2f;
float yOuterPos = -outerRadius / 2f + this.Height / 2f;
if (innerRadius != 0.0)
gp1.AddPie(xInnerPos, yInnerPos, innerRadius, innerRadius, startAngle, sweepAngle);
gp2.AddPie(xOuterPos, yOuterPos, outerRadius, outerRadius, startAngle, sweepAngle);
Region rg1 = new System.Drawing.Region(gp1);
Region rg2 = new System.Drawing.Region(gp2);
g.DrawPath(Pens.Transparent, gp1);
g.DrawPath(Pens.Transparent, gp2);
rg1.Xor(rg2);
g.FillRegion(Brushes.Black, rg1);
this.Region = rg1;
}
//Just for testing purpose. Place a breakpoint
//in here and you'll see it will only get called when
//you click inside the "pie" shape
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
}
}
编辑:通过将形状居中并为VS Designer添加属性,从另一个答案中窃取,使代码更好; - )
更多编辑:处理内半径== 0
的情况答案 1 :(得分:0)
尝试这个复杂形状控件的代码示例
您可以使用StartAngle
,SweepAngle
和InnerPercent
属性控制其形状。
public partial class PathUserControl : UserControl
{
private readonly GraphicsPath outerPath = new GraphicsPath();
private readonly GraphicsPath innerPath = new GraphicsPath();
private float startAngle;
private float sweepAngle = 60;
private float innerPercent = 30;
public PathUserControl()
{
base.BackColor = SystemColors.ControlDark;
}
[DefaultValue(0)]
[Description("The starting angle for the pie section, measured in degrees clockwise from the X-axis.")]
public float StartAngle
{
get { return startAngle; }
set
{
startAngle = value;
SetRegion();
}
}
[DefaultValue(60)]
[Description("The angle between StartAngle and the end of the pie section, measured in degrees clockwise from the X-axis.")]
public float SweepAngle
{
get { return sweepAngle; }
set
{
sweepAngle = value;
SetRegion();
}
}
[DefaultValue(30)]
[Description("Percent of the radius of the excluded inner area of the pie, measured from 0 to 100.")]
public float InnerPercent
{
get { return innerPercent; }
set
{
if (value < 0 || value > 100f)
throw new ArgumentOutOfRangeException("value", "Percent must be in the range 0 .. 100");
innerPercent = value;
SetRegion();
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
SetRegion();
}
private void SetRegion()
{
if (Region != null)
{
Region.Dispose();
Region = null;
}
if (ClientSize.IsEmpty)
return;
float innerCoef = 0.01f * InnerPercent;
outerPath.Reset();
innerPath.Reset();
outerPath.AddPie(0, 0, ClientSize.Width, ClientSize.Height, StartAngle, SweepAngle);
innerPath.AddPie(ClientSize.Width * (1 - innerCoef) / 2, ClientSize.Height * (1 - innerCoef) / 2, ClientSize.Width * innerCoef, ClientSize.Height * innerCoef, StartAngle, SweepAngle);
Region region = new Region(outerPath);
region.Xor(innerPath);
Region = region;
}
}
编辑带有XOR的@LucMorin想法很棒,我已经偷了它。