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

涉及知识点

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

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

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

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

温度计截图

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

温度计源码

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

1. Thermometer控件

Thermometer控件布局

<UserControl x:Class="WpfControl.UserControls.Thermometer"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:local="clr-namespace:WpfControl.UserControls"mc:Ignorable="d"d:DesignHeight="450" d:DesignWidth="150"><Grid><Grid.RowDefinitions><RowDefinition></RowDefinition><RowDefinition Height="auto"></RowDefinition></Grid.RowDefinitions><Rectangle StrokeThickness="7" RadiusX="40" RadiusY="15" Fill="White" /><Rectangle StrokeThickness="7" RadiusX="40" RadiusY="15"><Rectangle.Effect><DropShadowEffect ShadowDepth="0" Direction="0" BlurRadius="7" /></Rectangle.Effect><Rectangle.Stroke><LinearGradientBrush StartPoint="0,1" EndPoint="1,0"><LinearGradientBrush.RelativeTransform><RotateTransform Angle="40" CenterX="0.5" CenterY="0.5" /></LinearGradientBrush.RelativeTransform><GradientStop Color="Black" /><GradientStop Color="White" Offset="0.7" /></LinearGradientBrush></Rectangle.Stroke></Rectangle><TextBlock Text="℃" HorizontalAlignment="Center" VerticalAlignment="Top" FontWeight="Bold" FontSize="20" Margin="0, 20" Foreground="#555"/><Canvas Name="MainCanvas" Width="75" Margin="0,70" /><Border Width="10" RenderTransformOrigin="0.5,0.5" CornerRadius="5" Margin="0,50"><Border.Effect><DropShadowEffect ShadowDepth="0" Direction="0" Color="White" /></Border.Effect><Border.Background><LinearGradientBrush StartPoint="0,0" EndPoint="1,0"><GradientStop Color="lightGray" Offset="0" /><GradientStop Color="White" Offset="0.4" /><GradientStop Color="lightGray" Offset="1" /></LinearGradientBrush></Border.Background><Border Height="75" VerticalAlignment="Bottom" Name="BorValue"><Border.Background><LinearGradientBrush StartPoint="0,0" EndPoint="1,0"><GradientStop Color="#CD3333"  /><GradientStop Color="#FFC0CB" Offset="0.4" /><GradientStop Color="#CD3333" Offset="1" /></LinearGradientBrush></Border.Background></Border></Border><Border Height="25" Width="25" CornerRadius="15" VerticalAlignment="Bottom" Margin="0 0 0 30"><Border.Effect><DropShadowEffect Direction="0" ShadowDepth="0" /></Border.Effect><Border.Background><RadialGradientBrush Center="0.3,0.2" GradientOrigin="0.4,0.4"><GradientStop Color="White" Offset="0" /><GradientStop Color="#CD3333" Offset="1" /></RadialGradientBrush></Border.Background></Border><TextBox Grid.Row="1" Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Center" BorderThickness="0" BorderBrush="AliceBlue" VerticalAlignment="Bottom" FontSize="20" Name="ThermometerValue" /></Grid>
</UserControl>

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

namespace WpfControl.UserControls
{/// <summary>/// Thermometer.xaml 的交互逻辑/// </summary>public partial class Thermometer : UserControl{public int Minmum{get { return (int)GetValue(MinmumProperty); }set { SetValue(MinmumProperty, value); }}public static readonly DependencyProperty MinmumProperty =DependencyProperty.Register("Minmum", typeof(int), typeof(Thermometer), new PropertyMetadata(1, new PropertyChangedCallback(OnPropertyValueChanged)));public int Maxmum{get { return (int)GetValue(MaxmumProperty); }set { SetValue(MaxmumProperty, value); }}public static readonly DependencyProperty MaxmumProperty =DependencyProperty.Register("Maxmum", typeof(int), typeof(Thermometer), new PropertyMetadata(10, new PropertyChangedCallback(OnPropertyValueChanged)));public double Value{get { return (double)GetValue(ValueProperty); }set { SetValue(ValueProperty, value);}}public static readonly DependencyProperty ValueProperty =DependencyProperty.Register("Value", typeof(double), typeof(Thermometer), new PropertyMetadata(0.0, new PropertyChangedCallback(OnPropertyValueChanged)));/// <summary>/// 当属性值发生变化的时候直接更新UI内容/// </summary>/// <param name="d"></param>/// <param name="e"></param>private static void OnPropertyValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){(d as Thermometer)?.RefreshComponet();}private double step = 10;public Thermometer(){InitializeComponent();this.DataContext = this;}/// <summary>/// 刷新温度计上面的内容适应定义大小/// </summary>/// <exception cref="NotImplementedException"></exception>private void RefreshComponet(){// 两种方式触发:尺寸变化、区间变化var h = this.MainCanvas.ActualHeight;//通过这个判断界面元素是否加载if (h == 0) return;double w = 75;// 类型double stepCount = Maxmum - Minmum;// 在这个区间内多少个间隔step = h / (Maxmum - Minmum);// 每个间隔距离this.MainCanvas.Children.Clear();for (int i = 0; i <= stepCount; i++){Line line = new Line();line.Y1 = i * step;line.Y2 = i * step;line.Stroke = Brushes.Black;line.StrokeThickness = 1;this.MainCanvas.Children.Add(line);if (i % 10 == 0){line.X1 = 15;line.X2 = w - 15;// 添加文字TextBlock text = new TextBlock{Text = (Maxmum - i).ToString(),Width = 20,TextAlignment = TextAlignment.Center,FontSize = 9,Margin = new Thickness(0, -5, -4, 0)};Canvas.SetLeft(text, w - 15);Canvas.SetTop(text, i * step);this.MainCanvas.Children.Add(text);// 添加文字text = new TextBlock{Text = (Maxmum - i).ToString(),Width = 20,TextAlignment = TextAlignment.Center,FontSize = 9,Margin = new Thickness(-4, -5, 0, 0)};Canvas.SetLeft(text, 0);Canvas.SetTop(text, i * step);this.MainCanvas.Children.Add(text);}else if (i % 5 == 0){line.X1 = 20;line.X2 = w - 20;}else{line.X1 = 25;line.X2 = w - 25;}}ValueChanged();}private void ValueChanged() {// 限定值的变化范围var value = this.Value;if (this.Value < this.Minmum)value = this.Minmum;if (this.Value > this.Maxmum)value = this.Maxmum;// 温度值与Border的高度的一个转换var newValue = value - this.Minmum;newValue *= step;newValue += 20;// 动画DoubleAnimation doubleAnimation = new DoubleAnimation(newValue, TimeSpan.FromMilliseconds(500));this.BorValue.BeginAnimation(HeightProperty, doubleAnimation);}}}

2. 控件调用

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

<Windowxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:WpfControl"xmlns:UserControls="clr-namespace:WpfControl.UserControls" x:Class="WpfControl.TestWindow3"mc:Ignorable="d"Title="工控组态软件--温度计" Height="450" Width="1000" Loaded="Window_Loaded"><Grid><Grid.ColumnDefinitions><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition><ColumnDefinition></ColumnDefinition></Grid.ColumnDefinitions><Grid.RowDefinitions><RowDefinition></RowDefinition></Grid.RowDefinitions><UserControls:Thermometer Grid.Column="0" Grid.Row="0" x:Name="t1" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="1" Grid.Row="0" x:Name="t2" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="2" Grid.Row="0" x:Name="t3" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="3" Grid.Row="0" x:Name="t4" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="4" Grid.Row="0" x:Name="t5" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="5" Grid.Row="0" x:Name="t6" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="6" Grid.Row="0" x:Name="t7" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/><UserControls:Thermometer Grid.Column="7" Grid.Row="0" x:Name="t8" Width="100" Height="370" HorizontalAlignment="Center"  VerticalAlignment="Center"/></Grid>
</Window>

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

namespace WpfControl
{/// <summary>/// TestWindow3.xaml 的交互逻辑/// </summary>public partial class TestWindow3 : Window{public TestWindow3(){InitializeComponent();}private void Window_Loaded(object sender, RoutedEventArgs e){var controls = new Thermometer[8] { t1, t2 , t3, t4 , t5, t6 , t7, t8 };for (int i = 0; i < 8; i++) {controls[i].Maxmum = 100;controls[i].Minmum = -20;controls[i].Value = 10*(i+1);}}}
}

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

源码下载

备注

以上就是本篇文章的全部内容,旨在抛砖引玉,共同学习,一起进步。

WPF工控组态软件之温度计相关推荐

  1. WPF工控组态软件之冷却塔和空气压缩机开发

    WPF以其丰富灵活的控件样式设计,相较于WinForm而言,一直是工控组态软件的宠儿.经过上一篇文章的学习,已经对WPF开发工控组态软件有了一个基本的了解, 今天继续学习冷却塔和空气压缩机的开发,仅供 ...

  2. WPF工控组态软件之管道和冷却风扇开发

    WPF以其丰富灵活的控件样式设计,相较于WinForm而言,一直是工控组态软件的宠儿,本文以两个简单的小例子,简述如何通过WPF设计出表示水流的管道,和转动的冷却风扇.仅供学习分享使用,如有不足之处, ...

  3. 适应各种工控组态软件的图库,一款常用的工控图库,包括3D按钮 、箭头、对角线、多边形、鼓风机、锅炉、工厂等多种图形

    适应各种工控组态软件的图库,一款常用的工控图库,包括3D按钮 .箭头.对角线.多边形.鼓风机.锅炉.工厂等多种图形,有四千个图形,涵盖了所有行业的工控图形,种类丰富,可以满足您日常工控设计需求,支持e ...

  4. 工控 组态王6.60 SP3软件7.5 SP4 授权软件狗 USB 硬件狗 分享 下载

    工控 组态王6.60 SP3软件 授权软件狗 USB 硬件狗 分享 下载 技术咨询QQ:3137723307 组态王6.60是一款非常好用的工业类自动化控制软件,此版本继承了前面几个版本的所有功能,可 ...

  5. 金百福系统一直显示连接服务器,三维力控组态软件V7.2/7.1/7.0 新版加密狗无限点全授权...

    软件名称:三维力控组态软件V7.2/7.1/7.0 新版加密狗无限点全授权 三维力控组态软件,USB加密狗,送教学! [V7.2 最新版]: 无限点,全功能, 支持WEB发布,含所有扩展组件 温馨提醒 ...

  6. 力控批量添加变量_力控组态软件的变量操作函数1

    力控组态软件ForceControl V7.0的变量操作函数1 DisableOperate 语法DisableOperate (flag) 说明禁止用户对变量的操作. 参数flag:禁止标志.取值含 ...

  7. 力控组态软件后台组件Ado组件的控件方法及常用命令

    力控组态软件后台组件Ado组件的控件方法及常用命令 先在SQL SERVER中建立一个表Table_1,包含3个字段: d_t 日期时间型 int_1 整数型 float_1 浮点型 1.在配置> ...

  8. mysql关联力控_力控组态软件的专家报表的关系数据库函数

    力控组态软件ForceControl V7.0的专家报表的关系数据库函数 ExecuteSQL 语法: #report.ExecuteSQL(nSheetIndex, strSQL); 说明: 执行标 ...

  9. 力控 串口服务器 虚拟串口,M4系列串口服务器与力控组态软件MODBUS TCP 协议通信...

    软件需求:力控组态软件 力控 ForceControl V7.0 . 优势:无需虚拟串口软件做转发 2:MODBUS RTU 产品采用温湿度传感器读取温湿度指令是 11 04 00 00 00 02 ...

最新文章

  1. 敏捷开发中的故事点到底是什么?如何预估故事点?
  2. php修改后nginx返回不生效,nginx修改配置后不生效的问题
  3. win10之dlib安装 c++调用
  4. 【技术】一个由于时间问题引发的血案
  5. NetBeans 7 Python 又回来了
  6. 17、mybatis两个内置参数
  7. LeetCode 19 删除链表的倒数第 N 个结点
  8. thrift简单使用
  9. figma下载_如何在Figma中创建逼真的3D对象
  10. C语言综合期末作业,内蒙古农业大学2010年期末c语言综合作业.doc
  11. Berenson机器人艺术鉴赏家亮相切尔西画廊
  12. 人生赢家!带着宝宝去面试~清华90后女学霸范楚楚加入麻省理工MIT任助理教授!...
  13. 【回文串10】LeetCode 479. Largest Palindrome Product
  14. linux运行程序时,中途出现意外怎么办?
  15. C++学习笔记3:一些错误
  16. hashcat+john破解rar密码
  17. FTP服务器的上传文件端口为,FTP服务器上传文件时的端口
  18. 用决策树预测获胜球队
  19. Qt 之 HTTP 请求 多线程分块下载——上(获取下载文件大小)
  20. 如何启用计算机的无线功能键在哪,启动无线功能开关在哪

热门文章

  1. Modbus协议应用纪实
  2. 串行通信 - Modbus协议
  3. 配置org.springframework.scheduling.quartz.CronTriggerBean (转载)
  4. active英语怎么读音_inactive,inactive的英文意思和翻译,inactive的音标读音,用法,例句,发音,含义讲解...
  5. #PCIE# 8b/10b 编码
  6. JavaScript变量提升(Hoisting)详解
  7. SV学习(1)——数据类型
  8. activated钩子函数
  9. matlab 图案 柱状图_值得收藏 | 如何用matlab做出酷炫的图像
  10. Android仿微信图片编辑库,你想要的功能这里都有