开发者

WPF利用DrawingContext实现绘制温度计

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

上一篇:

下一篇:

精彩评论

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

最新开发

开发排行榜