|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Documents;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Media.Animation;
- using System.Windows.Media.Imaging;
- using System.Windows.Navigation;
- using System.Windows.Shapes;
-
- namespace BPASmartClient.CustomResource.UserControls
- {
- /// <summary>
- /// Instrument.xaml 的交互逻辑
- /// </summary>
- public partial class Instrument : UserControl
- {
- static bool ValueRefreshFlag = false;//值刷新标志
-
- #region 给仪表盘定义依赖属性
-
- #region Value:当前值 依赖属性
- //定义一个包装器
- /// <summary>
- /// 当前值
- /// </summary>
- public float Value
- {
- get { return (float)this.GetValue(ValueProperty); }
- set { this.SetValue(ValueProperty, value); }
- }
-
- //定义一个依赖属性 Register有三个参数,第一个是该属性的名称,第二个是该属性接受什么类型的数据,第三个是该属性属于哪个对象
- public static readonly DependencyProperty ValueProperty =
- DependencyProperty.Register("Value", typeof(float), typeof(Instrument),
- new PropertyMetadata(0.0f, new PropertyChangedCallback((d, e) =>
- {
- if (ValueRefreshFlag) (d as Instrument).ValueRefresh();
- else (d as Instrument).Refresh();
- })));
-
- //当 Value 的值更改的时候调用该委托
- public static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- (d as Instrument).Refresh();
- }
- #endregion
-
- #region Minimum:最小值 依赖属性
- /// <summary>
- /// 最小值
- /// </summary>
- public float Minimum
- {
- get { return (float)GetValue(MinimumProperty); }
- set { SetValue(MinimumProperty, value); }
- }
- public static readonly DependencyProperty MinimumProperty =
- DependencyProperty.Register("Minimum", typeof(float), typeof(Instrument),
- new PropertyMetadata(0.0f, new PropertyChangedCallback(OnPropertyChanged)));
-
- #endregion
-
- #region Maximum:最大值 依赖属性
- /// <summary>
- /// 最大值
- /// </summary>
- public float Maximum
- {
- get { return (float)GetValue(MaximumProperty); }
- set { SetValue(MaximumProperty, value); }
- }
- public static readonly DependencyProperty MaximumProperty =
- DependencyProperty.Register("Maximum", typeof(float), typeof(Instrument),
- new PropertyMetadata(100.0f, new PropertyChangedCallback(OnPropertyChanged)));
-
- #endregion
-
- #region Interval:分段间隔数 依赖属性
- /// <summary>
- /// 分段间隔数
- /// </summary>
- public int Interval
- {
- get { return (int)GetValue(IntervalProperty); }
- set { SetValue(IntervalProperty, value); }
- }
- public static readonly DependencyProperty IntervalProperty =
- DependencyProperty.Register("Interval", typeof(int), typeof(Instrument),
- new PropertyMetadata(10, new PropertyChangedCallback(OnPropertyChanged)));
- #endregion
-
- #region PlateBackground:仪表背景色 依赖属性
- /// <summary>
- /// 仪表背景色
- /// </summary>
- public Brush PlateBackground
- {
- get { return (Brush)GetValue(PlateBackgroundProperty); }
- set { SetValue(PlateBackgroundProperty, value); }
- }
-
- public static readonly DependencyProperty PlateBackgroundProperty =
- DependencyProperty.Register("PlateBackground", typeof(Brush), typeof(Instrument), new PropertyMetadata(new SolidColorBrush(Color.FromRgb(60, 60, 60))));
-
- #endregion
-
- #region ScaleTextSize:数值大小 依赖属性
- /// <summary>
- /// 数值大小
- /// </summary>
- public int ScaleTextSize
- {
- get { return (int)GetValue(ScaleTextSizeProperty); }
- set { SetValue(ScaleTextSizeProperty, value); }
- }
-
- public static readonly DependencyProperty ScaleTextSizeProperty =
- DependencyProperty.Register("ScaleTextSize", typeof(int), typeof(Instrument),
- new PropertyMetadata(14, new PropertyChangedCallback(OnPropertyChanged)));
-
- #endregion
-
- #region ScaleBrush:数值刻度颜色 依赖属性
- /// <summary>
- /// 数值刻度颜色
- /// </summary>
- public Brush ScaleBrush
- {
- get { return (Brush)GetValue(ScaleBrushProperty); }
- set { SetValue(ScaleBrushProperty, value); }
- }
- public static readonly DependencyProperty ScaleBrushProperty =
- DependencyProperty.Register("ScaleBrush", typeof(Brush), typeof(Instrument),
- new PropertyMetadata(new SolidColorBrush(Color.FromRgb(3, 182, 200)), new PropertyChangedCallback(OnPropertyChanged)));
-
- #endregion
-
- #region PointerColor:指针颜色 依赖属性
- public Brush PointerColor
- {
- get { return (Brush)GetValue(PointerColorProperty); }
- set { SetValue(PointerColorProperty, value); }
- }
- public static readonly DependencyProperty PointerColorProperty =
- DependencyProperty.Register("PointerColor", typeof(Brush), typeof(Instrument),
- new PropertyMetadata(new SolidColorBrush(Color.FromRgb(3, 182, 200)), new PropertyChangedCallback(OnPropertyChanged)));
- #endregion
-
- #region Unit:单位 依赖属性
- public string Unit
- {
- get { return (string)GetValue(UnitProperty); }
- set { SetValue(UnitProperty, value); }
- }
- public static readonly DependencyProperty UnitProperty =
- DependencyProperty.Register("Unit", typeof(string), typeof(Instrument),
- new PropertyMetadata("kg", new PropertyChangedCallback(OnPropertyChanged)));
- #endregion
-
- #region ScaleBrush:数值刻度颜色 依赖属性
-
- #endregion
-
- #endregion
-
- #region 值刷新
- private void ValueRefresh()
- {
- if (!ValueRefreshFlag) return;
- double radius = this.backEllipse.Width / 2;//获取仪表半径
- //指针当前值
- double step = 270.0 / (this.Maximum - this.Minimum);
- //this.rtPointer.Angle = this.Value * step - 45;
- double value = double.IsNaN(this.Value) ? 0 : this.Value;
-
- //指针动画显示
- DoubleAnimation da = new DoubleAnimation((value - this.Minimum) * step - 45, new Duration(TimeSpan.FromMilliseconds(500)));//指定动画的值
- this.rtPointer.BeginAnimation(RotateTransform.AngleProperty, da);//指定动画对象
-
- //指针绘制
- string sData = "M{0} {1},{1} {2},{1} {3}";
- sData = string.Format(sData, radius * 0.3, radius, radius - 5, radius + 5);
- var converter = TypeDescriptor.GetConverter(typeof(Geometry));
-
- Task.Run(new Action(() =>
- {
- Application.Current.Dispatcher.Invoke(new Action(() =>
- {
- this.pointer.Data = (Geometry)converter.ConvertFrom(sData);
- }));
- }));
-
- }
- #endregion
-
- #region 外观刷新
- private void Refresh()
- {
- double radius = this.backEllipse.Width / 2;//获取仪表半径
- if (double.IsNaN(radius)) return;
- if (this.Value < this.Minimum) return;
- if (this.Value > this.Maximum) return;
- this.mainCanvas.Children.Clear();//清空仪表画布
- double step = 270.0 / (this.Maximum - this.Minimum);//获取大刻度的角度
- //小刻度绘制
- for (int i = 0; i < this.Maximum - this.Minimum; i++)
- {
- Line lineScale = new Line();
-
- //接近圆心的点的坐标
- lineScale.X1 = radius - (radius - 13) * Math.Cos((i * step - 45) * Math.PI / 180);
- lineScale.Y1 = radius - (radius - 13) * Math.Sin((i * step - 45) * Math.PI / 180);
-
- //接近边框的点的坐标
- lineScale.X2 = radius - (radius - 8) * Math.Cos((i * step - 45) * Math.PI / 180);
- lineScale.Y2 = radius - (radius - 8) * Math.Sin((i * step - 45) * Math.PI / 180);
-
- lineScale.Stroke = this.ScaleBrush;//设置线条颜色
- lineScale.StrokeThickness = 1;//设置线条厚度
- this.mainCanvas.Children.Add(lineScale);
-
- }
-
- //大刻度绘制
- step = 270.0 / Interval;
- int TextScale = (int)this.Minimum;
- for (int i = 0; i <= Interval; i++)
- {
- Line lineScale = new Line();
-
- //接近圆心的点的坐标
- lineScale.X1 = radius - (radius - 20) * Math.Cos((i * step - 45) * Math.PI / 180);
- lineScale.Y1 = radius - (radius - 20) * Math.Sin((i * step - 45) * Math.PI / 180);
-
- //接近边框的点的坐标
- lineScale.X2 = radius - (radius - 8) * Math.Cos((i * step - 45) * Math.PI / 180);
- lineScale.Y2 = radius - (radius - 8) * Math.Sin((i * step - 45) * Math.PI / 180);
-
- lineScale.Stroke = this.ScaleBrush;//设置线条颜色
- lineScale.StrokeThickness = 1;//设置线条厚度
-
- this.mainCanvas.Children.Add(lineScale);
-
- //数值设置
- TextBlock textScale = new TextBlock();
- textScale.Width = 34;
- textScale.TextAlignment = TextAlignment.Center;
- textScale.FontSize = this.ScaleTextSize;
- textScale.Text = Math.Truncate((TextScale + (this.Maximum - this.Minimum) / Interval * i)).ToString();
- textScale.Foreground = this.ScaleBrush;
- Canvas.SetLeft(textScale, radius - (radius - 36) * Math.Cos((i * step - 45) * Math.PI / 180) - 17);//设置X轴坐标
- Canvas.SetTop(textScale, radius - (radius - 36) * Math.Sin((i * step - 45) * Math.PI / 180) - 10);//设置Y轴坐标
- this.mainCanvas.Children.Add(textScale);
- }
-
- //圆弧绘制
- string sData = "M{0} {1} A{0} {0} 0 1 1 {1} {2}";
- sData = string.Format(sData, radius / 2, radius, radius * 1.5);
- var converter = TypeDescriptor.GetConverter(typeof(Geometry));
- this.Circle.Data = (Geometry)converter.ConvertFrom(sData);
-
- ValueRefreshFlag = true;
- //指针当前值
- //step = 270.0 / (this.Maximum - this.Minimum);
- ////this.rtPointer.Angle = this.Value * step - 45;
- //double value = double.IsNaN(this.Value) ? 0 : this.Value;
- ////指针动画显示
- //DoubleAnimation da = new DoubleAnimation((value - this.Minimum) * step - 45, new Duration(TimeSpan.FromMilliseconds(500)));//指定动画的值
- //this.rtPointer.BeginAnimation(RotateTransform.AngleProperty, da);//指定动画对象
-
- ////指针绘制
- //sData = "M{0} {1},{1} {2},{1} {3}";
- //sData = string.Format(sData, radius * 0.3, radius, radius - 5, radius + 5);
- //this.pointer.Data = (Geometry)converter.ConvertFrom(sData);
-
- }
- #endregion
-
- public Instrument()
- {
- InitializeComponent();
- this.SizeChanged += Instrument_SizeChanged;
- this.Loaded += Instrument_Loaded;
- }
-
- private void Instrument_Loaded(object sender, RoutedEventArgs e)
- {
- Refresh();
- ValueRefresh();
- }
-
- private void Instrument_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- double minSize = Math.Min(this.RenderSize.Width, this.RenderSize.Height);
- this.backEllipse.Width = minSize;
- this.backEllipse.Height = minSize;
- }
- }
- }
|