开发者

WPF利用DrawingContext实现绘制温度计

开发者 https://www.devze.com 2022-12-02 11:12 出处:网络 作者: 驚鏵
wpF 使用 DrawingContext 绘制温度计 框架使用大于等于.NET40; Visual Studio 2022; 项目使用 MIT 开源许可协议;

wpF 使用 DrawingContext 绘制温度计

框架使用大于等于.NET40

Visual Studio 2022;

项目使用 MIT 开源许可协议;

定义Interval步长、MaxValue最大温度值、MinValue最小温度值。

CurrentGeometry 重新绘制当前刻度的Path值。

CurrentValue 当前值如果发生变化时则去重新CurrentGeometry 。

OnRender 绘制如下

  • RoundedRectangle温度计的外边框。
  • 使用方法DrawText 单字绘制 华氏温度文本Y轴变化。
  • 使用方法DrawText 单字绘制 摄氏温度文本Y轴变化。
  • 使用方法DrawText 绘制温度计两侧的刻度数值。
  • 使用方法DrawLine 绘制温度计两侧的刻度线。

WPF利用DrawingContext实现绘制温度计

实现代码

1) 准备Thermometer.cs如下:

usingSystem;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;

namespaceWPFDevelopers.Controls
{
publicclassThermometer:Control
smLmCTsI{
publicstaticreadonhttp://www.devze.comlyDependencyPropertyMaxValueProperty=
DependencyProperty.Register("MaxValue",typeof(double),typeof(Thermometer),newUIPropertyMetadata(40.0));

publicstaticreadonlyDependencyPropertyMinValueProperty=
DependencyProperty.Register("MinValue",typeof(double),typeof(Thermometer),newUIPropertyMetadata(-10.0));

///<summary>
///当前值
///</summary>
publicstaticreadonlyDependencyPropertyCurrentValueProperty=
DependencyProperty.Register("CurrentValue",typeof(double),typeof(Thermometer),
newUIPropertyMetadata(OnCurrentValueChanged));

///<summary>
///步长
///</summary>
publicstaticreadonlyDependencyPropertyIntervalProperty=
DependencyProperty.Register("Interval",typeof(double),typeof(Thermometer),newUIPropertyMetadata(10.0));

///<summary>
///当前值的图形坐标点
///</summary>
publicstaticreadonlyDependencyPropertyCurrentGeometryProperty=
DependencyProperty.Register("CurrentGeometry",typeof(Geometry),typeof(Thermometer),newPropertyMetadata(
Geometry.Parse(@"M2132.8
a440014-4
h18
a4400144
v32.2
a44001-44
h-18
a44001-4-4z")));

///<summary>
///构造函数
///</summary>
staticThermometer()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Thermometer),
nejswFrameworkPropertyMetadata(typeof(Thermometer)));
}

publicdoubleMaxValue
{
get=>(double)GetValue(MaxValueProperty);

set=>SetValue(MaxValueProperty,value);
}

publicdoubleMinValue
{
get=>(double)GetValue(MinValueProperty);

set=>SetValue(MinValueProperty,value);
}

publicdoubleCurrentValue
{
get=>(double)GetValue(CurrentValueProperty);

set
{
SetValue(CurrentValueProperty,value);

PaintPath();
}
}

publicdoubleInterval
{
get=>(double)GetValue(IntervalProperty);

set=>SetValue(IntervalProperty,value);
}

publicGeometryCurrentGeometry
{
get=>(Geometry)GetValue(CurrentGeometryProperty);

set=>SetValue(CurrentGeometryProperty,value);
}

privatestaticvoidOnCurrentValueChanged(DependencyObjectd,DependencyPropertyChangedEventArgse)
{
varthermometer=dasThermometer;
thermometer.CurrentValue=Convert.ToDouble(e.NewValue);
}

publicoverridevoidOnApplyTemplate()
{
base.OnApplyTemplate();

PaintPath();
}

protectedoverridevoidOnRender(DrawingContextdrawingContext)
{
varbrush=newSolidColorBrush((Color)ColorConverter.ConvertFromString("#82848A"));
varrect=newRect();
rect.Width=30;
rect.Height=169;
drawingContext.DrawRoundedRectangle(Brushes.Transparent,
newPen(brush,2d),
rect,8d,8d);

#region华氏温度

drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("华",
(Brush)DrawingContextjsHelper.BrushConverter.ConvertFromString("#82848A"),textSize:14D),
newPoint(-49,115));


drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("氏",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),textSize:14D),
newPoint(-49,115+14));


drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("温",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),textSize:14D),
newPoint(-49,115+28));


drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("度",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),textSize:14D),
newPoint(-49,115+42));

#endregion

#region摄氏温度

drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("摄",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),FlowDirection.LeftToRight,
14D),newPoint(75,115));


drawingContext.DrawText(
DrawingContextHelpe开发者_开发学习r.GetFormattedText("氏",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),FlowDirection.LeftToRight,
14D),newPoint(75,115+14));


drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("温",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),FlowDirection.LeftToRight,
14D),newPoint(75,115+28));


drawingContext.DrawText(
DrawingContextHelper.GetFormattedText("度",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),FlowDirection.LeftToRight,
14D),newPoint(75,115+42));

#endregion

#region画刻度

vartotal_Value=MaxValue-MinValue;

varcnt=total_Value/Interval;

varone_value=161d/cnt;

for(vari=0;i<=cnt;i++)
{
varformattedText=DrawingContextHelper.GetFormattedText($"{MaxValue-i*Interval}",
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#82848A"),FlowDirection.LeftToRight,
14D);

drawingContext.DrawText(formattedText,
newPoint(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,newPoint(-13,i*one_value-formattedText.Height/2d));

if(i!=0&&i!=5)
{
drawingContext.DrawLine(newPen(Brushes.Black,1d),
newPoint(4,i*one_value),newPoint(6,i*one_value));

drawingContext.DrawLine(newPen(Brushes.Black,1d),
newPoint(24,i*one_value),newPoint(26,i*one_value));
}
}

#endregion
}

///<summary>
///动态计算当前值图形坐标点
///</summary>
privatevoidPaintPath()
{
varone_value=161d/((MaxValue-MinValue)/Interval);

varwidth=26d;

varheight=169d-(MaxValue-CurrentValue)*(one_value/Interval);

varx=2d;

vary=169d-(169d-(MaxValue-CurrentValue)*编程客栈(one_value/Interval));


CurrentGeometry=Geometry.Parse($@"M2{y+4}
a440014-4
h{width-8}
a4400144
v{height-8}
a44001-44
h-{width-8}
a44001-4-4z");
}
}
}

2) 使用ThermometerExample.xaml.cs如下:

<UserControlx: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>

<BorderBackground="{DynamicResourceBackgroundSolidColorBrush}"
CornerRadius="12"
Width="400"Height="400"
Effect="{StaticResourceNormalShadowDepth}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Sliderx:Name="PART_Slider"IsSnapToTickEnabled="True"
Value="10"
Minimum="-10"
Maximum="40"
Orientation="Vertical"
Height="300"/>
<GridVerticalAlignment="Center"
Margin="160,0,0,0">
<PathFill="{StaticResourcePrimaryMouseoverSolidColorBrush}"
Stroke="{StaticResourcePrimaryMouseOverSolidColorBrush}"
StrokeThickness="1"Opacity=".6"
Data="{BindingElementName=PART_Thermometer,Path=CurrentGeometry,Mode=TwoWay}"/>
<wpfdev:Thermometerx:Name="PART_Thermometer"
CurrentValue="{BindingElementName=PART_Slider,Path=Value,Mode=TwoWay}"/>
</Grid>
<TextblockText="{BindingElementName=PART_Thermometer,Path=CurrentValue,StringFormat={}{0}℃}"
FontSize="24"Grid.Column="1"
Foreground="{StaticResourcePrimaryPressedSolidColorBrush}"FontFamily="Bahnschrift"
HorizontalAlignment="Center"VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
</UserControl>

实现效果

WPF利用DrawingContext实现绘制温度计

到此这篇关于WPF利用DrawingContext实现绘制温度计的文章就介绍到这了,更多相关WPF DrawingContext温度计内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

0

精彩评论

暂无评论...
验证码 换一张
取 消