網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
WPF 使用 DrawingContext 繪制溫度計(jì)
框架使用大于等于.NET40
;
Visual Studio 2022;
項(xiàng)目使用?MIT?開源許可協(xié)議;
定義Interval
步長(zhǎng)、MaxValue
最大溫度值、MinValue
最小溫度值。
CurrentGeometry
?重新繪制當(dāng)前刻度的Path
值。
CurrentValue
?當(dāng)前值如果發(fā)生變化時(shí)則去重新CurrentGeometry
?。
OnRender
?繪制如下
-
RoundedRectangle
溫度計(jì)的外邊框。 - 使用方法
DrawText
?單字繪制?華氏溫度
文本Y
軸變化。 - 使用方法
DrawText
?單字繪制?攝氏溫度
文本Y
軸變化。 - 使用方法
DrawText
?繪制溫度計(jì)兩側(cè)的刻度數(shù)值。 - 使用方法
DrawLine
?繪制溫度計(jì)兩側(cè)的刻度線。
實(shí)現(xiàn)代碼
1) 準(zhǔn)備Thermometer.cs如下:
using?System; 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?static?readonly?DependencyProperty?MinValueProperty?= ????????????DependencyProperty.Register("MinValue",?typeof(double),?typeof(Thermometer),?new?UIPropertyMetadata(-10.0)); ????????///?<summary> ????????///?????當(dāng)前值 ????????///?</summary> ????????public?static?readonly?DependencyProperty?CurrentValueProperty?= ????????????DependencyProperty.Register("CurrentValue",?typeof(double),?typeof(Thermometer), ????????????????new?UIPropertyMetadata(OnCurrentValueChanged)); ????????///?<summary> ????????///?????步長(zhǎng) ????????///?</summary> ????????public?static?readonly?DependencyProperty?IntervalProperty?= ????????????DependencyProperty.Register("Interval",?typeof(double),?typeof(Thermometer),?new?UIPropertyMetadata(10.0)); ????????///?<summary> ????????///?????當(dāng)前值的圖形坐標(biāo)點(diǎn) ????????///?</summary> ????????public?static?readonly?DependencyProperty?CurrentGeometryProperty?= ????????????DependencyProperty.Register("CurrentGeometry",?typeof(Geometry),?typeof(Thermometer),?new?PropertyMetadata( ????????????????Geometry.Parse(@"M?2?132.8 ??????????????????????????????a?4?4?0?0?1?4?-4 ??????????????????????????????h?18 ??????????????????????????????a?4?4?0?0?1?4?4 ??????????????????????????????v?32.2 ??????????????????????????????a?4?4?0?0?1?-4?4 ??????????????????????????????h?-18 ??????????????????????????????a?4?4?0?0?1?-4?-4?z"))); ????????///?<summary> ????????///?????構(gòu)造函數(shù) ????????///?</summary> ????????static?Thermometer() ????????{ ????????????DefaultStyleKeyProperty.OverrideMetadata(typeof(Thermometer), ????????????????new?FrameworkPropertyMetadata(typeof(Thermometer))); ????????} ????????public?double?MaxValue ????????{ ????????????get?=>?(double)GetValue(MaxValueProperty); ????????????set?=>?SetValue(MaxValueProperty,?value); ????????} ????????public?double?MinValue ????????{ ????????????get?=>?(double)GetValue(MinValueProperty); ????????????set?=>?SetValue(MinValueProperty,?value); ????????} ????????public?double?CurrentValue ????????{ ????????????get?=>?(double)GetValue(CurrentValueProperty); ????????????set ????????????{ ????????????????SetValue(CurrentValueProperty,?value); ????????????????PaintPath(); ????????????} ????????} ????????public?double?Interval ????????{ ????????????get?=>?(double)GetValue(IntervalProperty); ????????????set?=>?SetValue(IntervalProperty,?value); ????????} ????????public?Geometry?CurrentGeometry ????????{ ????????????get?=>?(Geometry)GetValue(CurrentGeometryProperty); ????????????set?=>?SetValue(CurrentGeometryProperty,?value); ????????} ????????private?static?void?OnCurrentValueChanged(DependencyObject?d,?DependencyPropertyChangedEventArgs?e) ????????{ ????????????var?thermometer?=?d?as?Thermometer; ????????????thermometer.CurrentValue?=?Convert.ToDouble(e.NewValue); ????????} ????????public?override?void?OnApplyTemplate() ????????{ ????????????base.OnApplyTemplate(); ????????????PaintPath(); ????????} ????????protected?override?void?OnRender(DrawingContext?drawingContext) ????????{ ????????????var?brush?=?new?SolidColorBrush((Color)ColorConverter.ConvertFromString("#82848A")); ????????????var?rect?=?new?Rect(); ????????????rect.Width?=?30; ????????????rect.Height?=?169; ????????????drawingContext.DrawRoundedRectangle(Brushes.Transparent, ????????????????new?Pen(brush,?2d), ????????????????rect,?8d,?8d); ????????????#region?華氏溫度 ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("華", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?textSize:?14D), ????????????????new?Point(-49,?115)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("氏", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?textSize:?14D), ????????????????new?Point(-49,?115?+?14)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("溫", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?textSize:?14D), ????????????????new?Point(-49,?115?+?28)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("度", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?textSize:?14D), ????????????????new?Point(-49,?115?+?42)); ????????????#endregion ????????????#region?攝氏溫度 ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("攝", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?FlowDirection.LeftToRight, ????????????????????14D),?new?Point(75,?115)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("氏", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?FlowDirection.LeftToRight, ????????????????????14D),?new?Point(75,?115?+?14)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("溫", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?FlowDirection.LeftToRight, ????????????????????14D),?new?Point(75,?115?+?28)); ????????????drawingContext.DrawText( ????????????????DrawingContextHelper.GetFormattedText("度", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?FlowDirection.LeftToRight, ????????????????????14D),?new?Point(75,?115?+?42)); ????????????#endregion ????????????#region?畫刻度 ????????????var?total_Value?=?MaxValue?-?MinValue; ????????????var?cnt?=?total_Value?/?Interval; ????????????var?one_value?=?161d?/?cnt; ????????????for?(var?i?=?0;?i?<=?cnt;?i++) ????????????{ ????????????????var?formattedText?=?DrawingContextHelper.GetFormattedText($"{MaxValue?-?i?*?Interval}", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?FlowDirection.LeftToRight, ????????????????????14D); ????????????????drawingContext.DrawText(formattedText, ????????????????????new?Point(43,?i?*?one_value?-?formattedText.Height?/?2d));?//減去字體高度的一半 ????????????????formattedText?=?DrawingContextHelper.GetFormattedText($"{(MaxValue?-?i?*?Interval)?*?1.8d?+?32d}", ????????????????????(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),?textSize:?14D); ????????????????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 ????????} ????????///?<summary> ????????///?????動(dòng)態(tài)計(jì)算當(dāng)前值圖形坐標(biāo)點(diǎn) ????????///?</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?-4 ??????????????????????????????h?{width?-?8} ??????????????????????????????a?4?4?0?0?1?4?4 ??????????????????????????????v?{height?-?8} ??????????????????????????????a?4?4?0?0?1?-4?4 ??????????????????????????????h?-{width?-?8} ??????????????????????????????a?4?4?0?0?1?-4?-4?z"); ????????} ????} }
2) 使用ThermometerExample.xaml.cs如下:
<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/WPFDevelopersOrg/WPFDevelopers" ?????????????xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews" ?????????????mc:Ignorable="d"? ?????????????d:DesignHeight="450"?d:DesignWidth="800"> ????<Grid> ????????<Border?Background="{DynamicResource?BackgroundSolidColorBrush}"? ????????????????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>
實(shí)現(xiàn)效果
原文鏈接:https://mp.weixin.qq.com/s/L5RTlt3e2WYLMvLQ82kfUg
相關(guān)推薦
- 2022-03-03 【css】page-break-after 頁(yè)面打印分頁(yè)屬性
- 2022-05-11 RabbitMq工作模式深度剖析與Spring整合MQ
- 2024-07-22 get 、set 、toString 方法的使用
- 2022-08-12 利用Python判斷文件的幾種方法及其優(yōu)劣對(duì)比_python
- 2021-12-12 超快速上手jupyter notebook快捷鍵操作(兩種模式一個(gè)快捷鍵)
- 2022-03-31 jenkins?實(shí)現(xiàn)shell腳本化定時(shí)執(zhí)行任務(wù)的方法_linux shell
- 2022-09-29 C++模板的特化超詳細(xì)精講_C 語(yǔ)言
- 2022-08-05 C語(yǔ)言示例講解if?else語(yǔ)句的用法_C 語(yǔ)言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支