WPF 实现温度计
WPF開發者QQ群:?340500857? | 微信群 -> 進入公眾號主頁?加入組織
? 在WPF中沒有現成的溫度計控件,所以我們自己實現一個。
? 微信群人數太多入群請添加小編微信號
(yanjinhuawechat)或(W_Feng_aiQ)邀請入群
(需備注WPF開發者)
PS:有更好的方式歡迎推薦。
01
—
代碼如下
一、創建?Thermometer.cs 繼承?Control代碼如下。
using System; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Media;namespace WPFDevelopers.Controls {public class Thermometer: Control{public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(40.0));public double MaxValue{get { return (double)GetValue(MaxValueProperty); }set { SetValue(MaxValueProperty, value); }}public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(-10.0));public double MinValue{get { return (double)GetValue(MinValueProperty); }set { SetValue(MinValueProperty, value); }}/// <summary>/// 當前值/// </summary>public static readonly DependencyProperty CurrentValueProperty = DependencyProperty.Register("CurrentValue", typeof(double), typeof(Thermometer), new UIPropertyMetadata(OnCurrentValueChanged));private static void OnCurrentValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){Thermometer thermometer = d as Thermometer;thermometer.CurrentValue = Convert.ToDouble(e.NewValue);}public double CurrentValue{get { return (double)GetValue(CurrentValueProperty); }set{SetValue(CurrentValueProperty, value);PaintPath();}}/// <summary>/// 步長/// </summary>public static readonly DependencyProperty IntervalProperty = DependencyProperty.Register("Interval", typeof(double), typeof(Thermometer), new UIPropertyMetadata(10.0));public double Interval{get { return (double)GetValue(IntervalProperty); }set { SetValue(IntervalProperty, value); }}/// <summary>/// 當前值的圖形坐標點/// </summary>public static readonly DependencyProperty CurrentGeometryProperty = DependencyProperty.Register("CurrentGeometry", typeof(Geometry), typeof(Thermometer), new PropertyMetadata(Geometry.Parse(@"M 2 132.8a 4 4 0 0 1 4 -4h 18a 4 4 0 0 1 4 4v 32.2a 4 4 0 0 1 -4 4h -18a 4 4 0 0 1 -4 -4 z")));public Geometry CurrentGeometry{get { return (Geometry)GetValue(CurrentGeometryProperty); }set { SetValue(CurrentGeometryProperty, value); }}/// <summary>/// 構造函數/// </summary>static Thermometer(){DefaultStyleKeyProperty.OverrideMetadata(typeof(Thermometer), new FrameworkPropertyMetadata(typeof(Thermometer)));}public override void OnApplyTemplate(){base.OnApplyTemplate();PaintPath();}protected override void OnRender(DrawingContext drawingContext){SolidColorBrush brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#82848A"));Rect rect = new Rect();rect.Width = 30;rect.Height = 169;drawingContext.DrawRoundedRectangle(Brushes.Transparent,new Pen(brush, 2d),rect, 8d, 8d);#region 華氏溫度drawingContext.DrawText(GetFormattedText("華"), new Point(-49, 115));drawingContext.DrawText(GetFormattedText("氏"), new Point(-49, 115 + 14));drawingContext.DrawText(GetFormattedText("溫"), new Point(-49, 115 + 28));drawingContext.DrawText(GetFormattedText("度"), new Point(-49, 115 + 42));#endregion#region 攝氏溫度drawingContext.DrawText(GetFormattedText("攝", FlowDirection.LeftToRight), new Point(75, 115));drawingContext.DrawText(GetFormattedText("氏", FlowDirection.LeftToRight), new Point(75, 115 + 14));drawingContext.DrawText(GetFormattedText("溫", FlowDirection.LeftToRight), new Point(75, 115 + 28));drawingContext.DrawText(GetFormattedText("度", FlowDirection.LeftToRight), new Point(75, 115 + 42));#endregion#region 畫刻度var total_Value = MaxValue - MinValue;var cnt = total_Value / Interval;var one_value = 161d / cnt;for (int i = 0; i <= cnt; i++){var formattedText = GetFormattedText($"{MaxValue - (i * Interval)}", FlowDirection.LeftToRight);drawingContext.DrawText(formattedText, new Point(43, i * one_value - (formattedText.Height / 2d)));//減去字體高度的一半formattedText = GetFormattedText($"{(MaxValue - (i * Interval)) * 1.8d + 32d}");drawingContext.DrawText(formattedText, new Point(-13, i * one_value - (formattedText.Height / 2d)));if (i != 0 && i != 5){drawingContext.DrawLine(new Pen(Brushes.Black, 1d),new Point(4, i * one_value), new Point(6, i * one_value));drawingContext.DrawLine(new Pen(Brushes.Black, 1d),new Point(24, i * one_value), new Point(26, i * one_value));}}#endregion}private FormattedText GetFormattedText(string text, FlowDirection flowDirection = FlowDirection.RightToLeft){return new FormattedText(text,CultureInfo.CurrentUICulture,flowDirection,new Typeface("Microsoft YaHei"),14d,new SolidColorBrush((Color)ColorConverter.ConvertFromString("#82848A")));}/// <summary>/// 動態計算當前值圖形坐標點/// </summary>private void PaintPath(){var one_value = 161d / ((MaxValue - MinValue) / Interval);var width = 26d;var height = 169d - (MaxValue - CurrentValue) * (one_value / Interval);var x = 2d;var y = 169d - (169d - (MaxValue - CurrentValue) * (one_value / Interval));CurrentGeometry = Geometry.Parse($@"M 2 {y + 4}a 4 4 0 0 1 4 -4h {width - 8}a 4 4 0 0 1 4 4v {height - 8}a 4 4 0 0 1 -4 4h -{width - 8}a 4 4 0 0 1 -4 -4 z");}} }二、創建ThermometerExample.xaml代碼如下
<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.ThermometerExample"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:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers"xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"><Grid><Border Background="White" CornerRadius="12"Width="400" Height="400"Effect="{StaticResource NormalShadowDepth}"><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><Slider x:Name="PART_Slider" IsSnapToTickEnabled="True"Value="10"Minimum="-10"Maximum="40" Orientation="Vertical"Height="300"/><Grid VerticalAlignment="Center"Margin="160,0,0,0"><Path Fill="{StaticResource PrimaryMouseOverSolidColorBrush}" Stroke="{StaticResource PrimaryMouseOverSolidColorBrush}"StrokeThickness="1" Opacity=".6"Data="{Binding ElementName=PART_Thermometer, Path=CurrentGeometry,Mode=TwoWay}"/><wpfdev:Thermometer x:Name="PART_Thermometer"CurrentValue="{Binding ElementName=PART_Slider,Path=Value,Mode=TwoWay}"/></Grid><TextBlock Text="{Binding ElementName=PART_Thermometer,Path=CurrentValue,StringFormat={}{0}℃}" FontSize="24" Grid.Column="1"Foreground="{StaticResource PrimaryPressedSolidColorBrush}" FontFamily="Bahnschrift"HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></Border></Grid> </UserControl>02
—
效果預覽
鳴謝素材提供者 - 帥嘉欣
源碼地址如下
github:https://github.com/yanjinhuagood/WPFDevelopers.git
gitee:https://gitee.com/yanjinhua/WPFDevelopers.git
WPF開發者QQ群:?340500857?
blogs:?https://www.cnblogs.com/yanjinhua
Github:https://github.com/yanjinhuagood
出處:https://www.cnblogs.com/yanjinhua
版權:本作品采用「署名-非商業性使用-相同方式共享 4.0 國際」許可協議進行許可。
轉載請著名作者 出處 https://github.com/yanjinhuagood
掃一掃關注我們,
更多知識早知道!
點擊閱讀原文可跳轉至源代碼
總結
- 上一篇: 如何限制并发的 异步IO 请求数量?
- 下一篇: C# 10 新特性 —— 补充篇