如何在c#中生成循环图?

如何在c#中生成循环图?,c#,animation,graph,C#,Animation,Graph,您好,我正在制作一个应用程序,设计需要特殊的图形,这些图形根据给定的值而变化。像这样: 我该怎么做呢?有人能给我指出正确的方向吗? 橙色的外圈随着值的变化而变化,但中间的圆圈保持静止 p、 我的绘画技巧令人惊叹。你可以很容易地画出自己的控制。最主要的是FillPie方法,它只绘制圆的一部分。要更改外圈的起点或填充方向,您需要在OnPaint事件的FillPie调用中更改起点和扫掠角度 using System; using System.Windows.Forms; using Syste

您好,我正在制作一个应用程序,设计需要特殊的图形,这些图形根据给定的值而变化。像这样:

我该怎么做呢?有人能给我指出正确的方向吗? 橙色的外圈随着值的变化而变化,但中间的圆圈保持静止


p、 我的绘画技巧令人惊叹。

你可以很容易地画出自己的控制。最主要的是
FillPie
方法,它只绘制圆的一部分。要更改外圈的起点或填充方向,您需要在
OnPaint
事件的
FillPie
调用中更改起点和扫掠角度

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

public class CircularProgressBar : Control
{

    #region "Properties"
    private Color _BorderColor;
    public Color BorderColor
    {
        get { return _BorderColor; }
        set
        {
            _BorderColor = value;
            this.Invalidate();
        }
    }

    private Color _InnerColor;
    public Color InnerColor
    {
        get { return _InnerColor; }
        set
        {
            _InnerColor = value;
            this.Invalidate();
        }
    }

    private bool _ShowPercentage;
    public bool ShowPercentage
    {
        get { return _ShowPercentage; }
        set
        {
            _ShowPercentage = value;
            this.Invalidate();
        }
    }

    private int _BorderWidth;
    public int BorderWidth
    {
        get { return _BorderWidth; }
        set
        {
            _BorderWidth = value;
            this.Invalidate();
        }
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
        set
        {
            _Value = value;
            this.Invalidate();
        }
    }

    #endregion

    #region "Constructor"
    public CircularProgressBar()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        _Value = 100;
        _BorderColor = Color.Orange;
        _BorderWidth = 30;
        _ShowPercentage = true;
        _InnerColor = Color.DarkGray;
        this.ForeColor = Color.White;
    }
    #endregion

    #region "Painting"
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Measure the single parts
        int Diameter = Math.Min(this.ClientSize.Width, this.ClientSize.Height);
        int InnerDiameter = Diameter - BorderWidth;
        Rectangle PieRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - Diameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - Diameter / 2), Diameter, Diameter);
        Rectangle InnerRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - InnerDiameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - InnerDiameter / 2), InnerDiameter, InnerDiameter);

        //Draw outer ring
        using (SolidBrush b = new SolidBrush(BorderColor))
        {
            e.Graphics.FillPie(b, PieRect, 0, Value / 100 * 360);
        }

        //Draw inner ring
        using (SolidBrush b = new SolidBrush(this._InnerColor))
        {
            e.Graphics.FillEllipse(b, InnerRect);
        }

        //Draw percentage
        if (ShowPercentage)
        {
            using (StringFormat sf = new StringFormat())
            {
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                using (SolidBrush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(Convert.ToInt32(Value).ToString() + "%", this.Font, b, InnerRect, sf);
                }
            }
        }
    }
    #endregion

}
结果是:

您可以非常轻松地绘制自己的控件。最主要的是
FillPie
方法,它只绘制圆的一部分。要更改外圈的起点或填充方向,您需要在
OnPaint
事件的
FillPie
调用中更改起点和扫掠角度

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

public class CircularProgressBar : Control
{

    #region "Properties"
    private Color _BorderColor;
    public Color BorderColor
    {
        get { return _BorderColor; }
        set
        {
            _BorderColor = value;
            this.Invalidate();
        }
    }

    private Color _InnerColor;
    public Color InnerColor
    {
        get { return _InnerColor; }
        set
        {
            _InnerColor = value;
            this.Invalidate();
        }
    }

    private bool _ShowPercentage;
    public bool ShowPercentage
    {
        get { return _ShowPercentage; }
        set
        {
            _ShowPercentage = value;
            this.Invalidate();
        }
    }

    private int _BorderWidth;
    public int BorderWidth
    {
        get { return _BorderWidth; }
        set
        {
            _BorderWidth = value;
            this.Invalidate();
        }
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
        set
        {
            _Value = value;
            this.Invalidate();
        }
    }

    #endregion

    #region "Constructor"
    public CircularProgressBar()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        _Value = 100;
        _BorderColor = Color.Orange;
        _BorderWidth = 30;
        _ShowPercentage = true;
        _InnerColor = Color.DarkGray;
        this.ForeColor = Color.White;
    }
    #endregion

    #region "Painting"
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Measure the single parts
        int Diameter = Math.Min(this.ClientSize.Width, this.ClientSize.Height);
        int InnerDiameter = Diameter - BorderWidth;
        Rectangle PieRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - Diameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - Diameter / 2), Diameter, Diameter);
        Rectangle InnerRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - InnerDiameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - InnerDiameter / 2), InnerDiameter, InnerDiameter);

        //Draw outer ring
        using (SolidBrush b = new SolidBrush(BorderColor))
        {
            e.Graphics.FillPie(b, PieRect, 0, Value / 100 * 360);
        }

        //Draw inner ring
        using (SolidBrush b = new SolidBrush(this._InnerColor))
        {
            e.Graphics.FillEllipse(b, InnerRect);
        }

        //Draw percentage
        if (ShowPercentage)
        {
            using (StringFormat sf = new StringFormat())
            {
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                using (SolidBrush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(Convert.ToInt32(Value).ToString() + "%", this.Font, b, InnerRect, sf);
                }
            }
        }
    }
    #endregion

}
结果是:

您可以非常轻松地绘制自己的控件。最主要的是
FillPie
方法,它只绘制圆的一部分。要更改外圈的起点或填充方向,您需要在
OnPaint
事件的
FillPie
调用中更改起点和扫掠角度

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

public class CircularProgressBar : Control
{

    #region "Properties"
    private Color _BorderColor;
    public Color BorderColor
    {
        get { return _BorderColor; }
        set
        {
            _BorderColor = value;
            this.Invalidate();
        }
    }

    private Color _InnerColor;
    public Color InnerColor
    {
        get { return _InnerColor; }
        set
        {
            _InnerColor = value;
            this.Invalidate();
        }
    }

    private bool _ShowPercentage;
    public bool ShowPercentage
    {
        get { return _ShowPercentage; }
        set
        {
            _ShowPercentage = value;
            this.Invalidate();
        }
    }

    private int _BorderWidth;
    public int BorderWidth
    {
        get { return _BorderWidth; }
        set
        {
            _BorderWidth = value;
            this.Invalidate();
        }
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
        set
        {
            _Value = value;
            this.Invalidate();
        }
    }

    #endregion

    #region "Constructor"
    public CircularProgressBar()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        _Value = 100;
        _BorderColor = Color.Orange;
        _BorderWidth = 30;
        _ShowPercentage = true;
        _InnerColor = Color.DarkGray;
        this.ForeColor = Color.White;
    }
    #endregion

    #region "Painting"
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Measure the single parts
        int Diameter = Math.Min(this.ClientSize.Width, this.ClientSize.Height);
        int InnerDiameter = Diameter - BorderWidth;
        Rectangle PieRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - Diameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - Diameter / 2), Diameter, Diameter);
        Rectangle InnerRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - InnerDiameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - InnerDiameter / 2), InnerDiameter, InnerDiameter);

        //Draw outer ring
        using (SolidBrush b = new SolidBrush(BorderColor))
        {
            e.Graphics.FillPie(b, PieRect, 0, Value / 100 * 360);
        }

        //Draw inner ring
        using (SolidBrush b = new SolidBrush(this._InnerColor))
        {
            e.Graphics.FillEllipse(b, InnerRect);
        }

        //Draw percentage
        if (ShowPercentage)
        {
            using (StringFormat sf = new StringFormat())
            {
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                using (SolidBrush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(Convert.ToInt32(Value).ToString() + "%", this.Font, b, InnerRect, sf);
                }
            }
        }
    }
    #endregion

}
结果是:

您可以非常轻松地绘制自己的控件。最主要的是
FillPie
方法,它只绘制圆的一部分。要更改外圈的起点或填充方向,您需要在
OnPaint
事件的
FillPie
调用中更改起点和扫掠角度

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;

public class CircularProgressBar : Control
{

    #region "Properties"
    private Color _BorderColor;
    public Color BorderColor
    {
        get { return _BorderColor; }
        set
        {
            _BorderColor = value;
            this.Invalidate();
        }
    }

    private Color _InnerColor;
    public Color InnerColor
    {
        get { return _InnerColor; }
        set
        {
            _InnerColor = value;
            this.Invalidate();
        }
    }

    private bool _ShowPercentage;
    public bool ShowPercentage
    {
        get { return _ShowPercentage; }
        set
        {
            _ShowPercentage = value;
            this.Invalidate();
        }
    }

    private int _BorderWidth;
    public int BorderWidth
    {
        get { return _BorderWidth; }
        set
        {
            _BorderWidth = value;
            this.Invalidate();
        }
    }

    private float _Value;
    public float Value
    {
        get { return _Value; }
        set
        {
            _Value = value;
            this.Invalidate();
        }
    }

    #endregion

    #region "Constructor"
    public CircularProgressBar()
    {
        SetStyle(ControlStyles.AllPaintingInWmPaint, true);
        SetStyle(ControlStyles.ResizeRedraw, true);
        SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
        _Value = 100;
        _BorderColor = Color.Orange;
        _BorderWidth = 30;
        _ShowPercentage = true;
        _InnerColor = Color.DarkGray;
        this.ForeColor = Color.White;
    }
    #endregion

    #region "Painting"
    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

        //Measure the single parts
        int Diameter = Math.Min(this.ClientSize.Width, this.ClientSize.Height);
        int InnerDiameter = Diameter - BorderWidth;
        Rectangle PieRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - Diameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - Diameter / 2), Diameter, Diameter);
        Rectangle InnerRect = new Rectangle(Convert.ToInt32(this.ClientSize.Width / 2 - InnerDiameter / 2), Convert.ToInt32(this.ClientSize.Height / 2 - InnerDiameter / 2), InnerDiameter, InnerDiameter);

        //Draw outer ring
        using (SolidBrush b = new SolidBrush(BorderColor))
        {
            e.Graphics.FillPie(b, PieRect, 0, Value / 100 * 360);
        }

        //Draw inner ring
        using (SolidBrush b = new SolidBrush(this._InnerColor))
        {
            e.Graphics.FillEllipse(b, InnerRect);
        }

        //Draw percentage
        if (ShowPercentage)
        {
            using (StringFormat sf = new StringFormat())
            {
                sf.Alignment = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Center;
                using (SolidBrush b = new SolidBrush(this.ForeColor))
                {
                    e.Graphics.DrawString(Convert.ToInt32(Value).ToString() + "%", this.Font, b, InnerRect, sf);
                }
            }
        }
    }
    #endregion

}
结果是:

那将是一个圆形图。球体是三维的。那将是一个圆形的图形。球体是三维的。那将是一个圆形的图形。球体是三维的。那将是一个圆形的图形。球体是三维的。这很好!简单的拉弧也可以。但这很酷@user3379346只需将类添加到项目中并编译即可。然后,您将在工具箱中找到该控件,就像其他控件一样。将“值”特性从0-100更改为调整圆弧。前景色和字体定义了如何绘制内部数字。谢谢你的帮助,我真的很感激。我还有一个问题。我能把它拿出来让它每5秒刷新一次吗?你为什么要这么做?控件将在任何时候发生更改时重新绘制,无需自己进行。如果需要,可以在窗体中添加一个计时器,并在tick事件中调用图上的Refresh,但这是一件奇怪的事情。表单上的值不会更改。因此,我认为我需要刷新它。这很好!简单的拉弧也可以。但这很酷@user3379346只需将类添加到项目中并编译即可。然后,您将在工具箱中找到该控件,就像其他控件一样。将“值”特性从0-100更改为调整圆弧。前景色和字体定义了如何绘制内部数字。谢谢你的帮助,我真的很感激。我还有一个问题。我能把它拿出来让它每5秒刷新一次吗?你为什么要这么做?控件将在任何时候发生更改时重新绘制,无需自己进行。如果需要,可以在窗体中添加一个计时器,并在tick事件中调用图上的Refresh,但这是一件奇怪的事情。表单上的值不会更改。因此,我认为我需要刷新它。这很好!简单的拉弧也可以。但这很酷@user3379346只需将类添加到项目中并编译即可。然后,您将在工具箱中找到该控件,就像其他控件一样。将“值”特性从0-100更改为调整圆弧。前景色和字体定义了如何绘制内部数字。谢谢你的帮助,我真的很感激。我还有一个问题。我能把它拿出来让它每5秒刷新一次吗?你为什么要这么做?控件将在任何时候发生更改时重新绘制,无需自己进行。如果需要,可以在窗体中添加一个计时器,并在tick事件中调用图上的Refresh,但这是一件奇怪的事情。表单上的值不会更改。因此,我认为我需要刷新它。这很好!简单的拉弧也可以。但这很酷@user3379346只需将类添加到项目中并编译即可。然后,您将在工具箱中找到该控件,就像其他控件一样。将“值”特性从0-100更改为调整圆弧。前景色和字体定义了如何绘制内部数字。谢谢你的帮助,我真的很感激。我还有一个问题。我能把它拿出来让它每5秒刷新一次吗?你为什么要这么做?控件将在任何时候发生更改时重新绘制,无需自己进行。如果需要,可以在窗体中添加一个计时器,并在tick事件中调用图上的Refresh,但这是一件奇怪的事情。表单上的值不会更改。因此,我认为我需要刷新它。