雷达扫描控件----------WinForm控件开发系列

雷达扫描控件----------WinForm控件开发系列

  /// <summary>
  /// 雷达扫描控件
  /// </summary>
  [ToolboxItem(true)]
  [DefaultProperty("Items")]
  [Description("雷达扫描控件")]
  public partial class RadarExt : Control
  {
    #region

    private Color areaColor = Color.LawnGreen;
    /// <summary>
    /// 雷达区域背景颜色
    /// </summary>
    [DefaultValue(typeof(Color), "LawnGreen")]
    [Description("雷达区域背景颜色")]
    public Color AreaColor
    {
      get { return this.areaColor; }
      set
      {
        if (this.areaColor == value)
          return;
        this.areaColor = value;
        this.Invalidate();
      }
    }

    private Color scanColor = Color.Coral;
    /// <summary>
    /// 雷达扫描背景颜色
    /// </summary>
    [DefaultValue(typeof(Color), "Coral")]
    [Description("雷达扫描背景颜色")]
    public Color ScanColor
    {
      get { return this.scanColor; }
      set
      {
        if (this.scanColor == value)
          return;
        this.scanColor = value;
        this.Invalidate();
      }
    }

    private bool areaCross = true;
    /// <summary>
    /// 雷达区域是否显示十字线
    /// </summary>
    [DefaultValue(true)]
    [Description("雷达区域是否显示十字线")]
    public bool AreaCross
    {
      get { return this.areaCross; }
      set
      {
        if (this.areaCross == value)
          return;
        this.areaCross = value;
        this.Invalidate();
      }
    }

    private Color areaCrossColor = Color.YellowGreen;
    /// <summary>
    /// 雷达区域十字线颜色
    /// </summary>
    [DefaultValue(typeof(Color), "YellowGreen")]
    [Description("雷达区域十字线颜色")]
    public Color AreaCrossColor
    {
      get { return this.areaCrossColor; }
      set
      {
        if (this.areaCrossColor == value)
          return;
        this.areaCrossColor = value;
        this.Invalidate();
      }
    }

    private bool pointFlicker = true;
    /// <summary>
    /// 坐标是否闪烁
    /// </summary>
    [DefaultValue(true)]
    [Description("坐标是否闪烁")]
    public bool PointFlicker
    {
      get { return this.pointFlicker; }
      set
      {
        if (this.pointFlicker == value)
          return;
        this.pointFlicker = value;
        this.flickerInterval.Enabled = value;
        this.Invalidate();
      }
    }

    private Color pointColor = Color.DeepSkyBlue;
    /// <summary>
    /// 坐标颜色
    /// </summary>
    [DefaultValue(typeof(Color), "DeepSkyBlue")]
    [Description("坐标颜色")]
    public Color PointColor
    {
      get { return this.pointColor; }
      set
      {
        if (this.pointColor == value)
          return;
        this.pointColor = value;
        this.Invalidate();
      }
    }

    private int pointDiameter = 4;
    /// <summary>
    /// 坐标圆点直径
    /// </summary>
    [DefaultValue(4)]
    [Description("坐标圆点直径")]
    public int PointDiameter
    {
      get { return this.pointDiameter; }
      set
      {
        if (this.pointDiameter == value)
          return;
        this.pointDiameter = value;
        this.Invalidate();
      }
    }

    private LinePointFCollection linePointFCollection;
    /// <summary>
    /// 坐标集合
    /// </summary>
    [DefaultValue(null)]
    [Description("坐标集合")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public LinePointFCollection Items
    {
      get
      {
        if (this.linePointFCollection == null)
          this.linePointFCollection = new LinePointFCollection(this);
        return this.linePointFCollection;
      }
    }

    private float proportion = 1;
    /// <summary>
    /// 坐标一像素表示实际长度(例如187.3表示一个像素代表实际187.3)
    /// </summary>
    [DefaultValue(1)]
    [Description("坐标一像素的实际比例")]
    public float Proportion
    {
      get { return this.proportion; }
      set
      {
        if (this.proportion == value)
          return;
        this.proportion = value;
        this.Invalidate();
      }
    }

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

    private Timer timeInterval;
    private Timer flickerInterval;
    private int angle = 0;
    private bool flickerStatus = false;

    #endregion

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

      InitializeComponent();
      this.timeInterval = new Timer();
      this.timeInterval.Interval = 50;
      this.timeInterval.Tick += new EventHandler(this.timeInterval_Tick);
      this.timeInterval.Enabled = true;

      this.flickerInterval = new Timer();
      this.flickerInterval.Interval = 500;
      this.flickerInterval.Tick += new EventHandler(this.flickerInterval_Tick);
      if (this.PointFlicker)
      {
        this.flickerInterval.Enabled = true;
      }
    }

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

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

      GraphicsPath graphicsPath = new GraphicsPath();
      graphicsPath.AddEllipse(rect);
      PathGradientBrush area_pgb = new PathGradientBrush(graphicsPath);
      area_pgb.CenterColor = this.AreaColor;
      area_pgb.CenterPoint = new PointF(rect.Width / 2, rect.Height / 2);
      area_pgb.SurroundColors = new Color[] { Color.Transparent };
      g.FillEllipse(area_pgb, rect);

      PathGradientBrush scan_pgb = new PathGradientBrush(graphicsPath);
      scan_pgb.CenterColor = this.ScanColor;
      scan_pgb.CenterPoint = new PointF(rect.Width / 2, rect.Height / 2);
      scan_pgb.SurroundColors = new Color[] { Color.Transparent };
      g.FillPie(scan_pgb, rect, this.angle, 90);

      area_pgb.Dispose();
      scan_pgb.Dispose();

      if (this.AreaCross)
      {
        PathGradientBrush cross_pgb = new PathGradientBrush(graphicsPath);
        cross_pgb.CenterColor = this.AreaCrossColor;
        cross_pgb.CenterPoint = new PointF(rect.Width / 2, rect.Height / 2);
        cross_pgb.SurroundColors = new Color[] { Color.Transparent };
        Pen cross_pen = new Pen(cross_pgb);
        g.DrawLine(cross_pen, 0, rect.Height / 2, rect.Width, rect.Height / 2);
        g.DrawLine(cross_pen, rect.Width / 2, 0, rect.Width / 2, rect.Height);
        cross_pgb.Dispose();
        cross_pen.Dispose();
      }

      if (!this.PointFlicker || (this.PointFlicker && this.flickerStatus))
      {
        Point point = new Point(rect.Width / 2, rect.Height / 2);
        for (int i = 0; i < Items.Count; i++)
        {
          int x = point.X + (int)(Items[i].X / this.Proportion) - this.PointDiameter / 2;
          int y = point.Y + (int)(Items[i].Y / this.Proportion) - this.PointDiameter / 2;
          if (graphicsPath.IsVisible(x, y))
          {
            SolidBrush point_sb = new SolidBrush(this.PointColor);
            g.FillEllipse(point_sb, new Rectangle(x, y, this.PointDiameter, this.PointDiameter));
            point_sb.Dispose();
          }
        }
      }
      graphicsPath.Dispose();
    }

    protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
    {
      base.SetBoundsCore(x, y, width, width, specified);
    }

    private void timeInterval_Tick(object sender, EventArgs e)
    {
      this.angle += 10;
      if (this.angle > 360)
        this.angle = this.angle - 360;
      this.Invalidate();
    }

    private void flickerInterval_Tick(object sender, EventArgs e)
    {
      this.flickerStatus = !this.flickerStatus;
      this.Invalidate();
    }

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

    /// <summary>
    /// 实际坐标集合
    /// </summary>
    [Description("实际坐标集合")]
    [Editor(typeof(CollectionEditorExt), typeof(UITypeEditor))]
    public sealed class LinePointFCollection : IList, ICollection, IEnumerable
    {
      private ArrayList linePointFList = new ArrayList();
      private RadarExt owner;

      public LinePointFCollection(RadarExt owner)
      {
        this.owner = owner;
      }

      #region IEnumerable

      public IEnumerator GetEnumerator()
      {
        LinePointF[] listArray = new LinePointF[this.linePointFList.Count];
        for (int index = 0; index < listArray.Length; ++index)
          listArray[index] = (LinePointF)this.linePointFList[index];
        return listArray.GetEnumerator();
      }

      #endregion

      #region ICollection

      public void CopyTo(Array array, int index)
      {
        for (int i = 0; i < this.Count; i++)
          array.SetValue(this.linePointFList[i], i + index);
      }

      public int Count
      {
        get
        {
          return this.linePointFList.Count;
        }
      }

      public bool IsSynchronized
      {
        get
        {
          return false;
        }
      }

      public object SyncRoot
      {
        get
        {
          return (object)this;
        }
      }

      #endregion

      #region IList

      public int Add(object value)
      {
        LinePointF linePointF = (LinePointF)value;
        this.linePointFList.Add(linePointF);
        this.owner.Invalidate();
        return this.Count - 1;
      }

      public void Clear()
      {
        this.linePointFList.Clear();
        this.owner.Invalidate();
      }

      public bool Contains(object value)
      {
        return this.IndexOf(value) != -1;
      }

      public int IndexOf(object value)
      {
        return this.linePointFList.IndexOf(value);
      }

      public void Insert(int index, object value)
      {
        throw new NotImplementedException();
      }

      public bool IsFixedSize
      {
        get { return false; }
      }

      public bool IsReadOnly
      {
        get { return false; }
      }

      public void Remove(object value)
      {
        if (!(value is LinePointF))
          return;
        this.linePointFList.Remove((LinePointF)value);
        this.owner.Invalidate();
      }

      public void RemoveAt(int index)
      {
        this.linePointFList.RemoveAt(index);
        this.owner.Invalidate();
      }

      public LinePointF this[int index]
      {
        get
        {
          return (LinePointF)this.linePointFList[index];
        }
        set
        {
          this.linePointFList[index] = (LinePointF)value;
          this.owner.Invalidate();
        }
      }

      object IList.this[int index]
      {
        get
        {
          return (object)this.linePointFList[index];
        }
        set
        {
          this.linePointFList[index] = (LinePointF)value;
          this.owner.Invalidate();
        }
      }

      #endregion

    }

    /// <summary>
    /// 实际坐标
    /// </summary>
    [Description("实际坐标")]
    public class LinePointF
    {
      /// <summary>
      /// X实际坐标
      /// </summary>
      [DefaultValue(0f)]
      [Description("X实际坐标")]
      public float X { get; set; }
      /// <summary>
      /// Y实际坐标
      /// </summary>
      [DefaultValue(0f)]
      [Description("Y实际坐标")]
      public float Y { get; set; }
    }

  }

 

 源码下载:雷达扫描控件.zip

雷达扫描控件----------WinForm控件开发系列

上一篇:温度计控件----------WinForm控件开发系列


下一篇:API接口版本控制