WPF自制动画 仪表盘控件 Gauge
public class ArcGauge : Control { public ArcGauge() { Width = 200; Height = 200; SetCurrentValue(ValueProperty, 0d); SetCurrentValue(MinValueProperty, 0d); SetCurrentValue(MaxValueProperty, 100d); } private void InitTick() { // 画大刻度 for (int i = 0; i < 9; i++) { Line line = new Line(); line.X1 = 0; line.Y1 = 0; line.X2 = 0; line.Y2 = 12; line.Stroke = Brushes.White; line.StrokeThickness = 2; line.HorizontalAlignment = HorizontalAlignment.Center; line.RenderTransformOrigin = new Point(0.5, 0.5); line.RenderTransform = new RotateTransform() { Angle = -140 + i * 35 }; bdGrid.Children.Add(line); DrawText(); } // 画小刻度 for (int i = 0; i < 8; i++) { var start = -140 + 35 * i + 3.5; for (int j = 0; j < 9; j++) { Line line = new Line(); line.X1 = 0; line.Y1 = 0; line.X2 = 0; line.Y2 = 6; line.Stroke = Brushes.White; line.StrokeThickness = 1; line.HorizontalAlignment = HorizontalAlignment.Center; line.RenderTransformOrigin = new Point(0.5, 0.5); line.RenderTransform = new RotateTransform() { Angle = start + j * 3.5 }; bdGrid.Children.Add(line); } } } List<TextBlock> textLabels = new List<TextBlock>(); private void DrawText() { foreach (var item in textLabels) { bdGrid.Children.Remove(item); } textLabels.Clear(); var per = MaxValue / 8; for (int i = 0; i < 9; i++) { TextBlock textBlock = new TextBlock(); textBlock.Text = $"{MinValue + (per * i)}"; textBlock.HorizontalAlignment = HorizontalAlignment.Center; textBlock.RenderTransformOrigin = new Point(0.5, 0.5); textBlock.RenderTransform = new RotateTransform() { Angle = -140 + i * 35 }; textBlock.Margin = new Thickness(12); textBlock.Foreground = Brushes.White; bdGrid.Children.Add(textBlock); textLabels.Add(textBlock); } } static ArcGauge() { DefaultStyleKeyProperty.OverrideMetadata(typeof(ArcGauge), new FrameworkPropertyMetadata(typeof(ArcGauge))); } RotateTransform rotateTransform; Grid bdGrid; public override void OnApplyTemplate() { base.OnApplyTemplate(); rotateTransform = GetTemplateChild("PointRotate") as RotateTransform; bdGrid = GetTemplateChild("bdGrid") as Grid; Refresh(); InitTick(); } [Category("值设定")] public double Value { get { return (double)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) => (d as ArcGauge)?.Refresh(); [Category("值设定")] public double MinValue { get { return (double)GetValue(MinValueProperty); } set { SetValue(MinValueProperty, value); } } public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); [Category("值设定")] public double MaxValue { get { return (double)GetValue(MaxValueProperty); } set { SetValue(MaxValueProperty, value); } } public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(ArcGauge), new PropertyMetadata(0d, OnValueChanged)); private void Refresh() { if (rotateTransform == null) return; DoubleAnimation da = new DoubleAnimation(); da.Duration = new Duration(TimeSpan.FromMilliseconds(350)); da.EasingFunction = new CubicEase() { EasingMode = EasingMode.EaseOut }; if (Value > MaxValue) { rotateTransform.Angle = 140; da.To = 140; } else if (Value < MinValue) { rotateTransform.Angle = -140; da.To = -140; } else { var range = MaxValue - MinValue; var process = Value / range; var tAngle = process * 280 - 140; rotateTransform.Angle = tAngle; da.To = tAngle; } rotateTransform.BeginAnimation(RotateTransform.AngleProperty, da); } }
<Style TargetType="{x:Type ctrl:ArcGauge}"> <Setter Property="Background" Value="#646464"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ctrl:ArcGauge}"> <Border Margin="10"> <Grid Width="{Binding RelativeSource={RelativeSource Self},Path=ActualHeight}"> <Ellipse Fill="#FF3B3B3B"/> <Grid RenderTransformOrigin="0.5,0.5" Margin="2"> <Grid.RenderTransform> <TransformGroup> <RotateTransform Angle="{Binding Path=Angle,ElementName=PointRotate}"/> </TransformGroup> </Grid.RenderTransform> <Ellipse Width="16" Height="14" Fill="Orange" VerticalAlignment="Top" > <Ellipse.Effect> <BlurEffect Radius="12"/> </Ellipse.Effect> </Ellipse> </Grid> <Grid x:Name="bdGrid" Margin="12" UseLayoutRounding="True" ClipToBounds="True"> <Ellipse> <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="#4D000000"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition Width="2*"/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="2*"/> <RowDefinition/> </Grid.RowDefinitions> <Ellipse Stroke="#464646" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> <Ellipse Stroke="#959595" Margin="4" StrokeThickness="6" Grid.Column="1" Grid.Row="1"/> <Ellipse Stroke="#464646" Margin="14" StrokeThickness="1" Grid.Column="1" Grid.Row="1"/> </Grid> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <Path Data="M5,0 5,0 10,120 0,120z" Fill="#0FA9CE" Stretch="Uniform" Margin="0 30 0 0" RenderTransformOrigin="0.5,1" HorizontalAlignment="Center"> <Path.RenderTransform> <TransformGroup> <RotateTransform x:Name="PointRotate"/> </TransformGroup> </Path.RenderTransform> </Path> </Grid> <Ellipse Width="28" Height="28" Fill="Black"> <Ellipse.Effect> <DropShadowEffect Color="#0FA9CE" ShadowDepth="0" Direction="0" BlurRadius="16"/> </Ellipse.Effect> </Ellipse> <Border VerticalAlignment="Bottom" BorderBrush="#10ABD1" BorderThickness="2" Margin="0 0 0 12" Background="Black" Padding="8 2" HorizontalAlignment="Center"> <TextBlock Text="{Binding Value,RelativeSource={RelativeSource Mode=TemplatedParent}}" FontSize="16" Width="30" TextAlignment="Center" Foreground="White" FontWeight="Bold"/> </Border> </Grid> </Grid> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
本文来自博客园,作者:willamyao,转载请注明原文链接:https://www.cnblogs.com/robertyao/p/17461256.html
代码改变世界