终端一体化运控平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

181 lines
7.5 KiB

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Windows.Controls;
  7. using System.Windows.Media.Animation;
  8. using System.Windows.Media;
  9. using System.Windows.Shapes;
  10. using System.Windows;
  11. using Microsoft.Expression.Shapes;
  12. namespace BPASmartClient.CustomResource.UserControls
  13. {
  14. public class Dashboard : System.Windows.Controls.Control
  15. {
  16. public const string ArcName = "arckd";
  17. public const string ValueTxtName = "valueTxt";
  18. public const string CanvasName = "canvasPlate";
  19. public const string ZZRotateName = "rtPointer";
  20. private static double StartAngle = -135.5;
  21. static Dashboard()
  22. {
  23. DefaultStyleKeyProperty.OverrideMetadata(typeof(Dashboard), new FrameworkPropertyMetadata(typeof(Dashboard)));
  24. }
  25. Arc arckd;
  26. TextBlock valueTxt;
  27. Canvas canvasPlate;
  28. RotateTransform rtPointer;
  29. public override void OnApplyTemplate()
  30. {
  31. base.OnApplyTemplate();
  32. if (arckd == null)
  33. arckd = GetTemplateChild(ArcName) as Arc;
  34. if (valueTxt == null)
  35. valueTxt = GetTemplateChild(ValueTxtName) as TextBlock;
  36. if (canvasPlate == null)
  37. canvasPlate = GetTemplateChild(CanvasName) as Canvas;
  38. if (rtPointer == null)
  39. rtPointer = GetTemplateChild(ZZRotateName) as RotateTransform;
  40. DrawScale();
  41. DrawAngle();
  42. arckd.EndAngle = StartAngle + (-StartAngle * 2d) * ((double)Value / Maximum);
  43. valueTxt.Text = Value.ToString();
  44. }
  45. public double Value
  46. {
  47. get { return (double)GetValue(ValueProperty); }
  48. set
  49. {
  50. SetValue(ValueProperty, value);
  51. }
  52. }
  53. public static readonly DependencyProperty ValueProperty =
  54. DependencyProperty.Register("Value", typeof(double), typeof(Dashboard),
  55. new PropertyMetadata(default(double), new PropertyChangedCallback(OnValuePropertyChanged)));
  56. public double Minimum
  57. {
  58. get { return (double)GetValue(MinimumProperty); }
  59. set { SetValue(MinimumProperty, value); }
  60. }
  61. public static readonly DependencyProperty MinimumProperty =
  62. DependencyProperty.Register("Minimum", typeof(double), typeof(Dashboard),
  63. new PropertyMetadata(double.NaN, new PropertyChangedCallback(OnPropertyChanged)));
  64. public double Maximum
  65. {
  66. get { return (double)GetValue(MaximumProperty); }
  67. set { SetValue(MaximumProperty, value); }
  68. }
  69. public static readonly DependencyProperty MaximumProperty =
  70. DependencyProperty.Register("Maximum", typeof(double), typeof(Dashboard),
  71. new PropertyMetadata(double.NaN, new PropertyChangedCallback(OnPropertyChanged)));
  72. public Brush PlateBackground
  73. {
  74. get { return (Brush)GetValue(PlateBackgroundProperty); }
  75. set { SetValue(PlateBackgroundProperty, value); }
  76. }
  77. public static readonly DependencyProperty PlateBackgroundProperty =
  78. DependencyProperty.Register("PlateBackground", typeof(Brush), typeof(Dashboard), null);
  79. public Brush PlateBorderBrush
  80. {
  81. get { return (Brush)GetValue(PlateBorderBrushProperty); }
  82. set { SetValue(PlateBorderBrushProperty, value); }
  83. }
  84. public static readonly DependencyProperty PlateBorderBrushProperty =
  85. DependencyProperty.Register("PlateBorderBrush", typeof(Brush), typeof(Dashboard), null);
  86. public Thickness PlateBorderThickness
  87. {
  88. get { return (Thickness)GetValue(PlateBorderThicknessProperty); }
  89. set { SetValue(PlateBorderThicknessProperty, value); }
  90. }
  91. public static readonly DependencyProperty PlateBorderThicknessProperty =
  92. DependencyProperty.Register("PlateBorderThickness", typeof(Thickness), typeof(Dashboard), null);
  93. public static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  94. {
  95. (d as Dashboard).DrawScale();
  96. }
  97. public static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  98. {
  99. Dashboard dashboard = d as Dashboard;
  100. dashboard.DrawAngle();
  101. if (dashboard.arckd == null)
  102. return;
  103. dashboard.arckd.EndAngle = StartAngle + (-StartAngle * 2d) * ((double)dashboard.Value / dashboard.Maximum);
  104. dashboard.valueTxt.Text = dashboard.Value.ToString();
  105. }
  106. /// <summary>
  107. /// 画表盘的刻度
  108. /// </summary>
  109. private void DrawScale()
  110. {
  111. if (this.canvasPlate == null) return;
  112. this.canvasPlate.Children.Clear();
  113. for (double i = 0; i <= this.Maximum - this.Minimum; i++)
  114. {
  115. //添加刻度线
  116. Line lineScale = new Line();
  117. if (i % 10 == 0)
  118. {
  119. //注意Math.Cos和Math.Sin的参数是弧度,记得将角度转为弧度制
  120. lineScale.X1 = 200 - 170 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  121. lineScale.Y1 = 200 - 170 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  122. lineScale.Stroke = new SolidColorBrush(Colors.White);
  123. lineScale.StrokeThickness = 2;
  124. //添加刻度值
  125. TextBlock txtScale = new TextBlock();
  126. txtScale.Text = (i + this.Minimum).ToString();
  127. txtScale.Width = 34;
  128. txtScale.TextAlignment = TextAlignment.Center;
  129. txtScale.Foreground = new SolidColorBrush(Colors.White);
  130. txtScale.RenderTransform = new RotateTransform() { Angle = 45, CenterX = 17, CenterY = 8 };
  131. txtScale.FontSize = 18;
  132. Canvas.SetLeft(txtScale, 200 - 155 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180) - 17);
  133. Canvas.SetTop(txtScale, 200 - 155 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180) - 10);
  134. this.canvasPlate.Children.Add(txtScale);
  135. }
  136. else
  137. {
  138. lineScale.X1 = 200 - 180 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  139. lineScale.Y1 = 200 - 180 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  140. lineScale.Stroke = new SolidColorBrush(Colors.White);
  141. lineScale.StrokeThickness = 1;
  142. lineScale.Opacity = 0.5;
  143. }
  144. lineScale.X2 = 200 - 190 * Math.Cos(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  145. lineScale.Y2 = 200 - 190 * Math.Sin(i * (270 / (this.Maximum - this.Minimum)) * Math.PI / 180);
  146. this.canvasPlate.Children.Add(lineScale);
  147. }
  148. }
  149. private void DrawAngle()
  150. {
  151. if (rtPointer == null)
  152. return;
  153. double step = 270.0 / (this.Maximum - this.Minimum);
  154. DoubleAnimation da = new DoubleAnimation(this.Value * step - 45, new Duration(TimeSpan.FromMilliseconds(200)));
  155. this.rtPointer.BeginAnimation(RotateTransform.AngleProperty, da);
  156. }
  157. }
  158. }