最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

WPF工控组态软件之温度计

来源:博客园

WPF以其丰富灵活的控件样式设计,相较于WinForm而言,一直是工控组态软件的宠儿。经过前两文章的学习,已经对WPF开发工控组态软件有了一个基本的了解, 今天继续学习温度计的开发,仅供学习分享使用,如有不足之处,还请指正。

各位关注【老码识途】的朋友们,因出差期间,一直使用公司具有文件加密和监控功能的电脑,无法发布原创文章。现在持续两个月的出差终于结束了,又可以发布原创博文了,后续会持续更新。

涉及知识点

在本示例中,主要知识点如下:


(资料图片仅供参考)

  • WPF阴影效果,线性渐变的设置,主要设置温度计的边框,填充等效果,形成一种金属质感。

  • WPF依赖属性设置,主要设置最大温度,最低温度,和当前温度值

  • WPF线条绘制,主要用于刻度

温度计截图

本示例主要实现功能为自定义刻度值,以及水银条随着当前温度值变化。具体如下所示:

温度计源码

示例源码分为以下2个部分:

1. Thermometer控件

Thermometer控件布局

1  9     10         11             12             13         14         15         16             17                 18             19             20                 21                     22                         23                     24                     25                     26                 27             28         29         30         31         32             33                 34             35             36                 37                     38                     39                     40                 41             42             43                 44                     45                         46                         47                         48                     49                 50             51         52         53             54                 55             56             57                 58                     59                     60                 61             62         63         64     65 

依赖属性设置及后台生成刻度源码,如下所示:

1 namespace WpfControl.UserControls  2 {  3     ///   4     /// Thermometer.xaml 的交互逻辑  5     ///   6     public partial class Thermometer : UserControl  7     {  8         public int Minmum  9         { 10             get { return (int)GetValue(MinmumProperty); } 11             set { SetValue(MinmumProperty, value); } 12         } 13  14         public static readonly DependencyProperty MinmumProperty = 15             DependencyProperty.Register("Minmum", typeof(int), typeof(Thermometer), new PropertyMetadata(1, new PropertyChangedCallback(OnPropertyValueChanged))); 16  17  18         public int Maxmum 19         { 20             get { return (int)GetValue(MaxmumProperty); } 21             set { SetValue(MaxmumProperty, value); } 22         } 23  24         public static readonly DependencyProperty MaxmumProperty = 25             DependencyProperty.Register("Maxmum", typeof(int), typeof(Thermometer), new PropertyMetadata(10, new PropertyChangedCallback(OnPropertyValueChanged))); 26  27  28  29         public double Value 30         { 31             get { return (double)GetValue(ValueProperty); } 32             set { SetValue(ValueProperty, value);} 33         } 34  35         public static readonly DependencyProperty ValueProperty = 36             DependencyProperty.Register("Value", typeof(double), typeof(Thermometer), new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyValueChanged))); 37  38         ///  39         /// 当属性值发生变化的时候直接更新UI内容 40         ///  41         ///  42         ///  43         private static void OnPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 44         { 45             (d as Thermometer)?.RefreshComponet(); 46         } 47  48         private double step = 10; 49  50         public Thermometer() 51         { 52             InitializeComponent(); 53             this.DataContext = this; 54         } 55  56         ///  57         /// 刷新温度计上面的内容适应定义大小 58         ///  59         ///  60         private void RefreshComponet() 61         { 62             // 两种方式触发:尺寸变化、区间变化 63             var h = this.MainCanvas.ActualHeight;//通过这个判断界面元素是否加载 64             if (h == 0) return; 65             double w = 75; 66             // 类型 67             double stepCount = Maxmum - Minmum;// 在这个区间内多少个间隔 68             step = h / (Maxmum - Minmum);// 每个间隔距离 69  70             this.MainCanvas.Children.Clear(); 71  72             for (int i = 0; i <= stepCount; i++) 73             { 74                 Line line = new Line(); 75                 line.Y1 = i * step; 76                 line.Y2 = i * step; 77                 line.Stroke = Brushes.Black; 78                 line.StrokeThickness = 1; 79                 this.MainCanvas.Children.Add(line); 80  81                 if (i % 10 == 0) 82                 { 83                     line.X1 = 15; 84                     line.X2 = w - 15; 85  86                     // 添加文字 87                     TextBlock text = new TextBlock 88                     { 89                         Text = (Maxmum - i).ToString(), 90                         Width = 20, 91                         TextAlignment = TextAlignment.Center, 92                         FontSize = 9, 93                         Margin = new Thickness(0, -5, -4, 0) 94                     }; 95                     Canvas.SetLeft(text, w - 15); 96                     Canvas.SetTop(text, i * step); 97                     this.MainCanvas.Children.Add(text); 98  99                     // 添加文字100                     text = new TextBlock101                     {102                         Text = (Maxmum - i).ToString(),103                         Width = 20,104                         TextAlignment = TextAlignment.Center,105                         FontSize = 9,106                         Margin = new Thickness(-4, -5, 0, 0)107                     };108                     Canvas.SetLeft(text, 0);109                     Canvas.SetTop(text, i * step);110                     this.MainCanvas.Children.Add(text);111                 }112                 else if (i % 5 == 0)113                 {114                     line.X1 = 20;115                     line.X2 = w - 20;116                 }117                 else118                 {119                     line.X1 = 25;120                     line.X2 = w - 25;121                 }122             }123             ValueChanged();124         }125 126 127         private void ValueChanged() {128             // 限定值的变化范围 129             var value = this.Value;130             if (this.Value < this.Minmum)131                 value = this.Minmum;132             if (this.Value > this.Maxmum)133                 value = this.Maxmum;134 135             // 温度值与Border的高度的一个转换136             var newValue = value - this.Minmum;137             newValue *= step;138             newValue += 20;139 140             // 动画141             DoubleAnimation doubleAnimation = new DoubleAnimation(newValue, TimeSpan.FromMilliseconds(500));142             this.BorValue.BeginAnimation(HeightProperty, doubleAnimation);143         }144 145     }146 147 }

2. 控件调用

用户控件不可以独立展示,需要以窗口为载体,作为窗口的一部分展示,页面调用如下所示:

1 10     11         12             13             14             15             16             17             18             19             20         21         22             23         24         25         26         27         28         29         30         31         32     33 

控件赋值,在窗口加载时,为控件赋初始值,如下所示:

1 namespace WpfControl 2 { 3     ///  4     /// TestWindow3.xaml 的交互逻辑 5     ///  6     public partial class TestWindow3 : Window 7     { 8         public TestWindow3() 9         {10             InitializeComponent();11         }12 13         private void Window_Loaded(object sender, RoutedEventArgs e)14         {15             var controls = new Thermometer[8] { t1, t2 , t3, t4 , t5, t6 , t7, t8 };16             for (int i = 0; i < 8; i++) {17                 controls[i].Maxmum = 100;18                 controls[i].Minmum = -20;19                 controls[i].Value = 10*(i+1);20             }21         }22     }23 }

注意:在实际业务中,可以通过对应的传输协议【如:Modbus等】从硬件获取,并实时的显示在页面中。

源码下载

关注【老码识途】公众号,然后回复MCGS即可,如下所示:

备注

以上就是本篇文章的全部内容,旨在抛砖引玉,共同学习,一起进步。学习编程,从关注【老码识途】开始!!!

关键词: 组态软件 属性设置 共同学习