[C.C++] WPF使用DrawingContext实现绘制刻度条

1880 0
王子 2022-11-10 12:23:48 | 显示全部楼层 |阅读模式
WPF 使用 DrawingContext 绘制刻度条
    框架使用大于等于.NET40;Visual Studio 2022;项目使用 MIT 开源许可协议;定义Interval步长、SpanInterval间隔步长、MiddleMask中间步长。当步长/ 间隔步长= 需要绘制的小刻度。循环绘制小刻度,判断当前j并取中间步长的模,如果模!=零就绘制中高线。从StartValue 开始绘制刻度到EndValue 结束刻度。CurrentGeometry 重新绘制当前刻度的Path值。CurrentValue 当前值如果发生变化时则去重新CurrentGeometry 。
1) 准备Ruler.cs如下:
usingSystem;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;

namespaceWPFDevelopers.Controls
{
publicclassRuler:Control
{
publicstaticreadonlyDependencyPropertyIntervalProperty=
DependencyProperty.Register("Interval",typeof(double),typeof(Ruler),newUIPropertyMetadata(30.0));

publicstaticreadonlyDependencyPropertySpanIntervalProperty=
DependencyProperty.Register("SpanInterval",typeof(double),typeof(Rulr),newUIPropertyMetadata(5.0));

publicstaticreadonlyDependencyPropertyMiddleMaskProperty=
DependencyProperty.Register("MiddleMask",typeof(int),typeof(Ruler),newUIPropertyMetadata(2));

publicstaticreadonlyDependencyPropertyCurrentValueProperty=
DependencyProperty.Register("CurrentValue",typeof(double),typeof(Ruler),
newUIPropertyMetadata(OnCurrentValueChanged));

publicstaticreadonlyDependencyPropertyStartValueProperty=
DependencyProperty.Register("StartValue",typeof(double),typeof(Ruler),newUIPropertyMetadata(120.0));

publicstaticreadonlyDependencyPropertyEndValueProperty=
DependencyProperty.Register("EndValue",typeof(double),typeof(Ruler),newUIPropertyMetadata(240.0));

publicstaticreadonlyDependencyPropertyCurrentGeometryProperty=
DependencyProperty.Register("CurrentGeometry",typeof(Geometry),typeof(Ruler),
newPropertyMetadata(Geometry.Parse("M257,0257,25264,49250,49257,25")));

staticRuler()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(Ruler),newFrameworkPropertyMetadata(typeof(Ruler)));
}

publicRuler()
{
Loaded+=Ruler_Loaded;
}

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

set=>SetValue(IntervalProperty,value);
}

publicdoubleSpanInterval
{
get=>(double)GetValue(SpanIntervalProperty);

set=>SetValue(SpanIntervalProperty,value);
}

publicintMiddleMask
{
get=>(int)GetValue(MiddleMaskProperty);

set=>SetValue(MiddleMaskProperty,value);
}

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

set
{
SetValue(CurrentValueProperty,value);
PaintPath();
}
}

publicdoubleStartValue
{
get=>(double)GetValue(StartValueProperty);

set=>SetValue(StartValueProperty,value);
}

publicdoubleEndValue
{
get=>(double)GetValue(EndValueProperty);

set=>SetValue(EndValueProperty,value);
}

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

set=>SetValue(CurrentGeometryProperty,value);
}

privatestaticvoidOnCurrentValueChanged(DependencyObjectd,DependencyPropertyChangedEventArgse)
{
varruler=dasRuler;
ruler.CurrentValue=Convert.ToDouble(e.NewValue);
}

protectedoverridevoidOnRender(DrawingContextdrawingContext)
{
RenderOptions.SetEdgeMode(this,EdgeMode.Aliased);
varnextLineValue=0d;
varone_Width=ActualWidth/((EndValue-StartValue)/Interval);

for(vari=0;i<=(EndValue-StartValue)/Interval;i++)
{
varnumberText=DrawingContextHelper.GetFormattedText((StartValue+i*Interval).ToString(),
(Brush)DrawingContextHelper.BrushConverter.ConvertFromString("#FFFFFF"),FlowDirection.LeftToRight,
10);
drawingContext.DrawText(numberText,newPoint(i*one_Width-8,0));
drawingContext.DrawLine(newPen(newSolidColorBrush(Colors.White),1),newPoint(i*one_Width,25),
newPoint(i*one_Width,ActualHeight-2));
varcnt=Interval/SpanInterval;
for(varj=1;j<=cnt;j++)
if(j%MiddleMask==0)
drawingContext.DrawLine(newPen(newSolidColorBrush(Colors.White),1),
newPoint(j*(one_Width/cnt)+nextLineValue,ActualHeight-2),
newPoint(j*(one_Width/cnt)+nextLineValue,ActualHeight-10));
else
drawingContext.DrawLine(newPen(newSolidColorBrush(Colors.White),1),
newPoint(j*(one_Width/cnt)+nextLineValue,ActualHeight-2),
newPoint(j*(one_Width/cnt)+nextLineValue,ActualHeight-5));

nextLineValue=i*one_Width;
}
}

privatevoidRuler_Loaded(objectsender,RoutedEventArgse)
{
PaintPath();
}

privatevoidPaintPath()
{
vard_Value=CurrentValue-StartValue;
varone_Value=ActualWidth/(EndValue-StartValue);
varx_Point=one_Value*d_Value+((double)Parent.GetValue(ActualWidthProperty)-ActualWidth)/2d;
CurrentGeometry=
Geometry.Parse($"M{x_Point},0{x_Point},25{x_Point+7},49{x_Point-7},49{x_Point},25");
}
}
}
2) 使用RulerControlExample.xaml.cs如下:
<UserControlx:Class="WPFDevelopers.Samples.ExampleViews.RulerControlExample"
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:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"
xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
mc:Ignorable="d"
d:DesignHeight="450"d:DesignWidth="800">
<Grid>
<Sliderx:Name="PART_Slider"IsSnapToTickEnabled="True"
Value="40"
Minimum="10"
Maximum="210"/>
<UniformGridRows="3">
<GridBackground="{StaticResourceCircularDualSolidColorBrush}"Height="51"Margin="40,0">
<PathStroke="{StaticResourceSuccessPressedSolidColorBrush}"StrokeThickness="1"Fill="{StaticResourceSuccessPressedSolidColorBrush}"
Data="{BindingElementName=PART_Ruler,Path=CurrentGeometry,Mode=TwoWay}"/>
<wpfdev:Rulerx:Name="PART_Ruler"Margin="40,0"Interval="20"StartValue="10"EndValue="210"
CurrentValue="{BindingElementName=PART_Slider,Path=Value,Mode=TwoWay}"/>
</Grid>
<GridBackground="{StaticResourceDangerPressedSolidColorBrush}"Height="51"Margin="40,0">
<PathStroke="{StaticResourceSuccessPressedSolidColorBrush}"StrokeThickness="1"Fill="{StaticResourceSuccessPressedSolidColorBrush}"
Data="{BindingElementName=PART_Ruler1,Path=CurrentGeometry,Mode=TwoWay}"/>
<wpfdev:Rulerx:Name="PART_Ruler1"Margin="40,0"Interval="20"StartValue="10"EndValue="210"
CurrentValue="{BindingElementName=PART_Slider,Path=Value,Mode=TwoWay}"/>
</Grid>
<GridBackground="{StaticResourceWarningPressedSolidColorBrush}"Height="51"Margin="40,0">
<PathStroke="{StaticResourceSuccessPressedSolidColorBrush}"StrokeThickness="1"Fill="{StaticResourceSuccessPressedSolidColorBrush}"
Data="{BindingElementName=PART_Ruler2,Path=CurrentGeometry,Mode=TwoWay}"/>
<wpfdev:Rulerx:Name="PART_Ruler2"Margin="40,0"Interval="20"StartValue="10"EndValue="210"
CurrentValue="{BindingElementName=PART_Slider,Path=Value,Mode=TwoWay}"/>
</Grid>
</UniformGrid>

</Grid>
</UserControl>

以上就是WPF使用DrawingContext实现绘制刻度条的详细内容,更多关于WPF刻度条的资料请关注中国红客联盟其它相关文章!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

中国红客联盟公众号

联系站长QQ:5520533

admin@chnhonker.com
Copyright © 2001-2025 Discuz Team. Powered by Discuz! X3.5 ( 粤ICP备13060014号 )|天天打卡 本站已运行