水波纹进度控件----------WinForm控件开发系列

拈花ヽ惹草 提交于 2020-11-16 00:29:34

/// <summary>
  /// 水波纹进度控件
  /// </summary>
  [ToolboxItem(true)]
  [DefaultProperty("Value")]
  [DefaultEvent("ValueChanged")]
  [Description("水波纹进度控件")]
  public partial class WaveProgressExt : Control
  {
    public delegate void ValueEventHandler(object sender, ValueEventArgs e);

    #region

    private event ValueEventHandler valueChanged;
    /// <summary>
    /// 进度值更改事件
    /// </summary>
    [Description("进度值更改事件")]
    public event ValueEventHandler ValueChanged
    {
      add { this.valueChanged += value; }
      remove { this.valueChanged -= value; }
    }

    private WaveProgressType type = WaveProgressType.Circle;
    /// <summary>
    /// 外观类型
    /// </summary>
    [DefaultValue(WaveProgressType.Circle)]
    [Description("外观类型")]
    public WaveProgressType Type
    {
      get { return this.type; }
      set
      {
        if (this.type == value)
          return;
        this.type = value;
        this.Invalidate();
      }
    }

    private bool active = false;
    /// <summary>
    /// 动画状态
    /// </summary>
    [DefaultValue(false)]
    [Description("动画状态")]
    public bool Active
    {
      get { return this.active; }
      set
      {
        if (this.active == value)
          return;
        this.active = value;
        this.waveTimer.Enabled = value;
      }
    }

    private bool borderShow = true;
    /// <summary>
    /// 是否显示边框
    /// </summary>
    [DefaultValue(true)]
    [Description("是否显示边框")]
    public bool BorderShow
    {
      get { return this.borderShow; }
      set
      {
        if (this.borderShow == value)
          return;
        this.borderShow = value;
        this.Invalidate();
      }
    }

    #region 水波纹

    private int waveInterval = 5;
    /// <summary>
    /// 水波纹移动速度
    /// </summary>
    [DefaultValue(5)]
    [Description("水波纹移动速度")]
    public int WaveInterval
    {
      get { return this.waveInterval; }
      set
      {
        if (this.waveInterval == value || value < 0)
          return;
        this.waveInterval = value;
      }
    }

    private float waveTension = 0.5f;
    /// <summary>
    /// 水波纹曲线的张力(0-1)
    /// </summary>
    [DefaultValue(0.5f)]
    [Description("水波纹曲线的张力(0-1)")]
    public float WaveTension
    {
      get { return this.waveTension; }
      set
      {
        if (this.waveTension == value || value < 0 || value > 1)
          return;
        this.waveTension = value;
        this.InitializeWave();
        this.Invalidate();
      }
    }

    private int waveWidth = 30;
    /// <summary>
    /// 水波纹宽度
    /// </summary>
    [DefaultValue(30)]
    [Description("水波纹宽度")]
    public int WaveWidth
    {
      get { return this.waveWidth; }
      set
      {
        if (this.waveWidth == value || value < 1)
          return;
        this.waveWidth = value;
        this.InitializeWave();
        this.Invalidate();
      }
    }

    private int waveHeight = 10;
    /// <summary>
    /// 水波纹高度
    /// </summary>
    [DefaultValue(10)]
    [Description("水波纹高度")]
    public int WaveHeight
    {
      get { return this.waveHeight; }
      set
      {
        if (this.waveHeight == value || value < 1)
          return;
        this.waveHeight = value;
        this.InitializeWave();
        this.Invalidate();
      }
    }

    private Color waveBackColor = Color.Empty;
    /// <summary>
    /// 水波纹背景颜色
    /// </summary>
    [DefaultValue(typeof(Color), "Empty")]
    [Description("水波纹背景颜色")]
    [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
    public Color WaveBackColor
    {
      get { return this.waveBackColor; }
      set
      {
        if (this.waveBackColor == value)
          return;
        this.waveBackColor = value;
        this.Invalidate();
      }
    }

    private Color waveFrontColor = Color.FromArgb(104, 135, 206, 250);
    /// <summary>
    /// 水波纹前方颜色
    /// </summary>
    [DefaultValue(typeof(Color), "104, 135, 206, 250")]
    [Description("水波纹前方颜色")]
    [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
    public Color WaveFrontColor
    {
      get { return this.waveFrontColor; }
      set
      {
        if (this.waveFrontColor == value)
          return;
        this.waveFrontColor = value;
        this.Invalidate();
      }
    }

    private Color waveBehindColor = Color.FromArgb(104, 135, 206, 250);
    /// <summary>
    /// 水波纹后方颜色
    /// </summary>
    [DefaultValue(typeof(Color), "104, 135, 206, 250")]
    [Description("水波纹后方颜色")]
    [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
    public Color WaveBehindColor
    {
      get { return this.waveBehindColor; }
      set
      {
        if (this.waveBehindColor == value)
          return;
        this.waveBehindColor = value;
        this.Invalidate();
      }
    }

    #endregion

    #region 进度值

    private bool valueShow = true;
    /// <summary>
    /// 是否显示进度值
    /// </summary>
    [DefaultValue(true)]
    [Description("是否显示进度值")]
    public bool ValueShow
    {
      get { return this.valueShow; }
      set
      {
        if (this.valueShow == value)
          return;
        this.valueShow = value;
        this.Invalidate();
      }
    }

    private float value = 0.0f;
    /// <summary>
    /// 进度值(0-1)
    /// </summary>
    [DefaultValue(0.0f)]
    [Description("进度值")]
    public float Value
    {
      get { return this.value; }
      set
      {
        if (this.value == value)
          return;
        if (value > 1)
          value = 1;
        if (value < 0)
          value = 0;
        this.value = value;
        this.Invalidate();
        if (this.valueChanged != null)
        {
          this.valueChanged(this, new ValueEventArgs() { Value = value });
        }
      }
    }

    private Font valueFont = new Font("宋体", 13, FontStyle.Bold);
    /// <summary>
    /// 进度值字体
    /// </summary>
    [DefaultValue(typeof(Font), "13pt style=Bold")]
    [Description("进度值字体")]
    public Font ValueFont
    {
      get { return this.valueFont; }
      set
      {
        if (this.valueFont == value)
          return;
        this.valueFont = value;
        this.Invalidate();
      }
    }

    private Color valueColor = Color.FromArgb(183, 240, 128, 128);
    /// <summary>
    /// 进度值颜色
    /// </summary>
    [DefaultValue(typeof(Color), "183, 240, 128, 128")]
    [Description("进度值颜色")]
    [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
    public Color ValueColor
    {
      get { return this.valueColor; }
      set
      {
        if (this.valueColor == value)
          return;
        this.valueColor = value;
        this.Invalidate();
      }
    }

    #endregion

    [Editor(typeof(ColorEditorExt), typeof(System.Drawing.Design.UITypeEditor))]
    public override Color BackColor
    {
      get
      {
        return base.BackColor;
      }
      set
      {
        base.BackColor = value;
      }
    }

    protected override Size DefaultSize
    {
      get
      {
        return new Size(100, 100); ;
      }
    }

    /// <summary>
    /// 水波纹移动定时器
    /// </summary>
    private Timer waveTimer;
    /// <summary>
    /// 水波纹移动距离
    /// </summary>
    int wave_distance = 0;
    /// <summary>
    /// 前面水波纹坐标
    /// </summary>
    List<Point> waveFrontPointList = new List<Point>();
    /// <summary>
    /// 后面水波纹坐标
    /// </summary>
    List<Point> waveBehindPointList = new List<Point>();

    #endregion

    public WaveProgressExt()
    {
      SetStyle(ControlStyles.UserPaint, true);
      SetStyle(ControlStyles.AllPaintingInWmPaint, true);
      SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
      SetStyle(ControlStyles.ResizeRedraw, true);
      SetStyle(ControlStyles.SupportsTransparentBackColor, true);
      InitializeComponent();

      this.InitializeWave();

      this.waveTimer = new Timer();
      this.waveTimer.Interval = 100;
      this.waveTimer.Tick += new EventHandler(this.time_Tick);
    }

    protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
    {
      base.OnPaint(e);

      Graphics g = e.Graphics;
      Rectangle rect = e.ClipRectangle;
      g.SmoothingMode = SmoothingMode.AntiAlias;

      if (this.Type == WaveProgressType.Circle)
      {
        GraphicsPath gp = new GraphicsPath();
        gp.AddEllipse(rect);
        g.SetClip(gp);
        gp.Dispose();
      }

      #region 水波纹背景
      if (this.WaveBackColor != Color.Empty)
      {
        SolidBrush waveback_sb = new SolidBrush(this.WaveBackColor);
        if (this.Type == WaveProgressType.Circle)
          g.FillEllipse(waveback_sb, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));
        else
          g.FillRectangle(waveback_sb, new Rectangle(rect.X, rect.Y, rect.Width - 2, rect.Height - 2));
        waveback_sb.Dispose();
      }
      #endregion

      #region 水波纹
      if (this.waveFrontPointList.Count > 0)
      {
        SolidBrush behind_sb = new SolidBrush(this.WaveBehindColor);
        SolidBrush front_sb = new SolidBrush(this.WaveFrontColor);

        Point[] behindPoint = new Point[this.waveFrontPointList.Count + 2];
        Point[] frontPoint = new Point[this.waveFrontPointList.Count + 2];

        int value_h = (int)(this.Value * rect.Height);
        for (int i = 0; i < this.waveFrontPointList.Count; i++)
        {
          behindPoint[i] = new Point(this.waveBehindPointList[i].X - this.wave_distance, rect.Bottom - this.waveBehindPointList[i].Y - value_h + this.WaveHeight / 3);
          frontPoint[i] = new Point(this.waveFrontPointList[i].X + this.wave_distance, rect.Bottom - this.waveFrontPointList[i].Y - value_h);
        }

        behindPoint[this.waveFrontPointList.Count] = new Point(behindPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
        behindPoint[this.waveFrontPointList.Count + 1] = new Point(behindPoint[0].X, rect.Bottom);

        frontPoint[this.waveFrontPointList.Count] = new Point(frontPoint[this.waveFrontPointList.Count - 1].X, rect.Bottom);
        frontPoint[this.waveFrontPointList.Count + 1] = new Point(frontPoint[0].X, rect.Bottom);

        g.FillClosedCurve(behind_sb, behindPoint, FillMode.Alternate, this.WaveTension);
        g.FillClosedCurve(front_sb, frontPoint, FillMode.Alternate, this.WaveTension);
        front_sb.Dispose();
        behind_sb.Dispose();

        #region 进度值
        if (this.ValueShow)
        {
          g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
          string value_str = (this.Value * 100).ToString("F0").PadLeft(3, ' ') + "%";
          Size value_size = TextRenderer.MeasureText(value_str, this.ValueFont, new Size(), TextFormatFlags.NoPadding);
          Rectangle value_rect = new Rectangle((rect.Width - value_size.Width) / 2, (rect.Height - value_size.Height) / 2, value_size.Width, value_size.Height);
          TextRenderer.DrawText(g, value_str, this.ValueFont, value_rect, this.ValueColor, TextFormatFlags.NoPadding);
        }
        #endregion

        #region 边框
        if (this.Type == WaveProgressType.Circle)
        {
          //利用背景色消除锯齿
          Pen back_pen = new Pen(this.BackColor);
          g.DrawEllipse(back_pen, rect);
          back_pen.Dispose();

          if (this.BorderShow)
          {
            Pen border_pen = new Pen(this.WaveFrontColor, 2);
            g.DrawEllipse(border_pen, new Rectangle(rect.X + 2, rect.Y + 2, rect.Width - 4, rect.Height - 4));
            border_pen.Dispose();
          }
        }
        else
        {
          if (this.BorderShow)
          {
            Pen border_pen = new Pen(this.WaveFrontColor, 2);
            g.DrawRectangle(border_pen, new Rectangle(rect.X, rect.Y, rect.Width - 2, rect.Height - 2));
            border_pen.Dispose();
          }
        }
        #endregion

      }
      #endregion

    }

    protected override void OnResize(EventArgs e)
    {
      base.OnResize(e);
      this.InitializeWave();
    }

    /// <summary>
    /// 水波纹移动动画
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void time_Tick(object sender, EventArgs e)
    {
      this.wave_distance += this.WaveInterval;
      if (this.wave_distance >= this.WaveWidth * 2)
      {
        this.wave_distance = 0;
      }
      this.Invalidate();
    }

    /// <summary>
    /// 初始化波浪纹
    /// </summary>
    protected void InitializeWave()
    {
      this.waveFrontPointList.Clear();
      this.waveBehindPointList.Clear();
      int startFront_x = this.ClientRectangle.X - this.WaveWidth * 4;
      int start_y = 0;
      int startBehind_x = this.ClientRectangle.Right + this.WaveWidth * 4;

      int i = 0;
      while (true)
      {
        startFront_x += this.WaveWidth;
        startBehind_x -= this.WaveWidth;
        start_y = this.WaveHeight * (i % 2);
        this.waveFrontPointList.Add(new Point(startFront_x, start_y));
        this.waveBehindPointList.Add(new Point(startBehind_x, start_y));
        if (startFront_x >= this.ClientRectangle.Right && start_y == 0)
        {
          this.wave_distance = 0;
          return;
        }
        i++;
      }

    }

    protected override void Dispose(bool disposing)
    {
      if (disposing && (components != null))
      {
        components.Dispose();
        if (this.waveTimer != null)
        {
          this.waveTimer.Dispose();
        }
      }
      base.Dispose(disposing);
    }

    /// <summary>
    /// 外观类型
    /// </summary>
    [Description("外观类型")]
    public enum WaveProgressType
    {
      /// <summary>
      /// 四边形
      /// </summary>
      Flat,
      /// <summary>
      /// 圆形
      /// </summary>
      Circle
    }

    /// <summary>
    /// 进度值更改事件参数
    /// </summary>
    [Description("进度值更改事件参数")]
    public class ValueEventArgs : EventArgs
    {
      /// <summary>
      /// 进度值
      /// </summary>
      [Description("进度值")]
      public float Value { get; set; }
    }
  }

源码下载:水波纹进度控件.zip

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!