public partial class RadarExt: Control { Private the Timer timeInterval; Private the Timer flickerInterval; Private int angle = 0 ; Private BOOL flickerStatus = to false ; Private Color areaColor = Color.LawnGreen; /// <Summary> /// radar background color region // / </ Summary> [the DefaultValue ( typeof (color), " LawnGreen " )] [the Description ( " radar background color area " )] 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")] [The Description ( " Radar Background Color Scanning " )] public Color ScanColor { GET { return the this .scanColor;} SET { IF ( the this .scanColor == value) return ; the this .scanColor = value; the this .Invalidate (); } } Private BOOL areaCross = to true ; /// <Summary> /// radar display area is crosshairs /// </ Summary> [the DefaultValue (to true)] [The Description ( " the radar display area is crosshairs " )] public BOOL AreaCross { GET { return the this .areaCross;} SET { IF ( the this .areaCross == value) return ; the this .areaCross = value; the this .Invalidate ( ); } } Private color areaCrossColor = Color.YELLOWGREEN; /// <Summary> /// radar cross line color region /// </ 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; The this .pointColor = value; the this .Invalidate (); } } Private int pointDiameter = . 4 ; /// <Summary> /// coordinate dot diameter /// </ Summary> [the DefaultValue ( . 4 )] [the Description ( " coordinate dot diameter " )] public int PointDiameter { GET { return the this .pointDiameter;} SET { IF ( the this .pointDiameter == value) return; this.pointDiameter = value; this.Invalidate(); } } private List<XY> items; /// <summary> /// 坐标 /// </summary> [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] [Description("坐标")] public List<XY> Items { get { if (this.items == null) this.items = new new List <the XY> (); return the this .items; } SET { the this .items = value; the this .Invalidate (); } } Private a float Proportion = . 1 ; /// <Summary> /// coordinates of a pixel represents the actual length (e.g., a pixel representing the actual denotes 187.3 187.3) /// </ Summary> [the DefaultValue ( . 1 )] [the Description ( " coordinates of a pixel in the actual proportion " )] public a 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); } } 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(); } } } g.SmoothingMode = SmoothingMode.Default; 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> public class XY { /// <summary> /// X实际坐标 /// </summary> [DefaultValue(0)] public float X { get; set; } /// <summary> /// Y实际坐标 /// </summary> [DefaultValue(0)] public float Y { get; set; } } }