#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点开始

效果:
评论区