创建一个没有提示的饼形自定义控件

本文关键字:提示 自定义控件 一个 创建 | 更新日期: 2023-09-27 17:50:41

我想创建一个自己的控件与饼的形式没有它的尖端,就像在图片之后。我只是不知道如何让它工作。
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);

这是我第一次使用自定义控件,所以很抱歉,如果我问的有点傻。

创建一个没有提示的饼形自定义控件

试试这个:

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设计器,偷从另一个答案;-)

更多编辑:考虑内半径== 0

试试这个复杂形状控件的代码示例。
你可以利用StartAngle, SweepAngleInnerPercent的性质来控制它的形状。

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的想法很棒,我偷来的