日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

WPF利用DrawingContext實(shí)現(xiàn)繪制溫度計(jì)_C#教程

作者:驚鏵 ? 更新時(shí)間: 2022-11-17 編程語(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

欄目分類
最近更新