#region 公共参数 // 原点位置 Point Opos = new Point(200, 200); //总角度 double angle = 360; // 角度 //取模 private static int num = 0; //刻度值0~100 private int externalNum = 0; //最大刻度 private int MaxScale = 51; //最小刻度 private int MinScale = 0; //实际会绘制角度 double drawAngle = 280.00; //圆的半径 double radius = 200; // 圆半径 #endregion public delegate void ExecuteMethodDelegate(); public MainWindow() { InitializeComponent(); } private Dictionary<string, Line> dicLine = new Dictionary<string, Line>(); private int _num = 0; /// <summary> /// 画表盘的刻度 /// </summary> private void ExternalScale() { this.radius = MainCanvas.Width / 2; double min = MinScale; double max = MaxScale; double step = drawAngle / (max - min); for (int i = 0; i < max - min; i++) { double angle1 = WrapAngle(i * step) + 90 + (360 - drawAngle) / 2; angle1 = ConvertDegreesToRadians(angle1); #region 绘制外圈线 { Line lineScale = new Line { X1 = (radius) * Math.Cos(angle1), Y1 = (radius) * Math.Sin(angle1), X2 = (radius - 15) * Math.Cos(angle1), Y2 = (radius - 15) * Math.Sin(angle1), Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)), StrokeThickness = 8 }; lineScale.Name = "line_" + _num; Canvas.SetLeft(lineScale, Opos.X); Canvas.SetTop(lineScale, Opos.Y); MainCanvas.Children.Add(lineScale); dicLine.Add("line_" + _num, lineScale); _num += 2; } #endregion #region 绘制内圈点和数值 { Action<int, double, double> action = (t1, t2, t3) => { Ellipse ellipse = new Ellipse { Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)), StrokeThickness = t1, Fill = new SolidColorBrush(Color.FromRgb(227, 227, 226)) }; ellipse.SetValue(Canvas.LeftProperty, t2 - 5); ellipse.SetValue(Canvas.TopProperty, t3 - 5); MainCanvas.Children.Add(ellipse); }; //double _step = externalNum >= 60 ? step - 0.28 : externalNum > 40 ? step - 0.149 : step;//刻度进行微调 double x1 = (radius - 45) * Math.Cos(angle1) + radius; double y1 = (radius - 52) * Math.Sin(angle1) + radius; if (num % 5 == 0) { //if (externalNum == 50) //{ // action(7, x1, y1); //} //else //{ action(8, x1, y1); //} //添加刻度值 TextBlock txtScale = new TextBlock(); txtScale.Text = Convert.ToString(externalNum); txtScale.FontSize = 10; if (externalNum == 50) { Canvas.SetLeft(txtScale, ((radius - 65) * Math.Cos(angle1)) + radius - 6.6); Canvas.SetTop(txtScale, ((radius - 65) * Math.Sin(angle1)) + radius - 8); } else { Canvas.SetLeft(txtScale, ((radius - 65) * Math.Cos(angle1)) + radius - 6.6); Canvas.SetTop(txtScale, ((radius - 65) * Math.Sin(angle1)) + radius - 8); } MainCanvas.Children.Add(txtScale); externalNum = externalNum + 10; num = 0; } else { action(4, x1, y1); } num++; } #endregion } RotationAngle(0);//指针归零位 DrawOCircle(); } /// <summary> /// 圆形表心圆 /// </summary> private void DrawOCircle() { Ellipse ellipseO = new Ellipse(); ellipseO.Width = 5; ellipseO.Height = 5; ellipseO.Fill = Brushes.Black; Canvas.SetLeft(ellipseO, Opos.X - 2.5); Canvas.SetTop(ellipseO, Opos.Y - 2.5); //if (MainCanvas.Children.Contains(ellipseO)) // MainCanvas.Children.Remove(ellipseO); MainCanvas.Children.Add(ellipseO); } /// <summary> /// 计算指针旋转角度 /// </summary> /// <param name="degrees"></param> /// <param name="maxNum"></param> /// <param name="minNum"></param> private void RotationAngle(double degrees) { double maxNum = 100; double minNum = 0; //表盘最小值 0 //表盘最大值 100 double span = maxNum - minNum; double v = maxNum / span; var row = drawAngle / MaxScale * (degrees - MinScale) * v / 2 - 142; this.PointerCanvas.RenderTransform = SetAngleXY(row, Opos.X, Opos.Y); DispatcherHelper.UpdateUI(); } /// <summary> /// 角度360度进制 /// </summary> /// <param name="angle"></param> /// <returns></returns> private double WrapAngle(double angle) { return angle % 360; } /// <summary> /// 将角度转为弧度 /// </summary> /// <param name="degrees"></param> /// <returns></returns> private double ConvertDegreesToRadians(double degrees) { double radians = (Math.PI / 180) * degrees; return radians; } /// <summary> /// 设置旋转角度和位置 /// </summary> /// <param name="Angle">角度</param> /// <param name="CenterX">X轴偏移位置</param> /// <param name="CenterY">X轴偏移位置</param> /// <returns></returns> public TransformGroup SetAngleXY(double Angle, double CenterX, double CenterY) { TransformGroup tfGroup = new TransformGroup(); RotateTransform rt = new RotateTransform(); rt.Angle = Angle; rt.CenterX = CenterX; rt.CenterY = CenterY; tfGroup.Children.Add(rt); return tfGroup; } private void MainWindow_OnLoaded(object sender, RoutedEventArgs e) { try { ExecuteMethodDelegate scale = ExternalScale; this.Dispatcher.BeginInvoke(scale); //scale?.BeginInvoke(null,null); } catch (Exception exception) { Console.WriteLine(exception); throw exception; } } public delegate void RotationAngleDelegate(double i); private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { double PreviousValue = 0, NextValue = 0; double[] arr = new double[] { 0, 1, 1.5, 2.5, 3.5, 7, 8.9, 9, 9.19, 9.23, 9.56, 9.58, 9.88, 9.99, 10.0, 10.12, 11, 12, 12.5, 15, 15.1, 15.23, 15.26, 15.27, 15.28, 15.5, 15.7, 15.9, 15.9, 16.12, 16.4, 16.8, 12.5 }; //数值移动 foreach (var item in arr) { PreviousValue = NextValue; NextValue = item; if (NextValue >= PreviousValue)//下一个值大于上一个值 { for (int i = 0; i < item; i += 2) { dicLine.TryGetValue("line_" + i, out Line line); if (line != null) { line.Stroke = Brushes.Red; } } } else { for (int i = Convert.ToInt32(NextValue) + 2; i <= PreviousValue; i += 2) { dicLine.TryGetValue("line_" + i, out Line line); if (line != null) { line.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); } } } RotationAngleDelegate rotationAngle = RotationAngle; this.Dispatcher.Invoke(rotationAngle, item); Thread.Sleep(200); Console.WriteLine($"i的值:{item}"); } } private void ResetBtn_OnClick(object sender, RoutedEventArgs e) { RotationAngleDelegate rotationAngle = RotationAngle; rotationAngle.Invoke(0); foreach (var item in dicLine) { item.Value.Stroke = new SolidColorBrush(Color.FromRgb(227, 227, 226)); } }
前台代码:
<Canvas x:Name="MainCanvas" Width="400" Height="400"> </Canvas> <Canvas x:Name="PointerCanvas" Width="{Binding Width,ElementName=MainCanvas}" Height="{Binding Height,ElementName=MainCanvas}"> <Path Stroke="Black" Canvas.Left="187.5" Canvas.Top="2" StrokeThickness="0"> <Path.Data> <PathGeometry> <PathGeometry.Figures> <PathFigure StartPoint="5,200" IsClosed="True"> <PathFigure.Segments> <LineSegment Point="17,80" ></LineSegment> <LineSegment Point="19,201" ></LineSegment> <LineSegment Point="12,208" ></LineSegment> </PathFigure.Segments> </PathFigure> </PathGeometry.Figures> </PathGeometry> </Path.Data> <Path.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="#F7D47E" Offset="0.25"></GradientStop> <GradientStop Color="#F5CE72" Offset="0.5"></GradientStop> <GradientStop Color="#F4B33C" Offset="0.75"></GradientStop> <GradientStop Color="#F3A71C" Offset="1"></GradientStop> </LinearGradientBrush> </Path.Fill> </Path> </Canvas> <Button Content="Button" HorizontalAlignment="Left" Click="ButtonBase_OnClick" Margin="30,38,0,0" VerticalAlignment="Top" Width="76"/> <Button Content="重置" HorizontalAlignment="Left" Click="ResetBtn_OnClick" Margin="30,97,0,0" VerticalAlignment="Top" Width="74"/>
注:
这里解析一下:+ 90 + (360 - drawAngle) / 2 是为什么(下面的图也是从别人那偷来的)
如果按照图示:+ 90 + (360 - 240) / 2 ;240是指绘制的表盘是多少度。起点是从右边0点开始
效果:
评论区