/// <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