• WPF 自定义控件 动画仪表盘控件 Gauge


    原文网址:https://blog.csdn.net/weixin_42850577/article/details/124008594

    WPF 自制动画 仪表盘控件 Gauge

    Xaml代码:

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

    C#代码:

    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);
    }
    }
    ————————————————
    版权声明:本文为CSDN博主「不知名君」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_42850577/article/details/124008594

  • 相关阅读:
    NOI2017 游戏
    2-SAT问题的方案输出
    hdu 2433 Travel
    bzoj千题计划230:bzoj3205: [Apio2013]机器人
    bzoj千题计划229:bzoj4424: Cf19E Fairy
    hdu 6166 Senior Pan
    poj 2404 Jogging Trails
    Oracle 删除数据后释放数据文件所占磁盘空间
    安装LINUX X86-64的10201出现链接ins_ctx.mk错误
    10G之后统计信息收集后为什么执行计划不会被立马淘汰
  • 原文地址:https://www.cnblogs.com/bruce1992/p/16863620.html
Copyright © 2020-2023  润新知