WPF实现仪表盘(刻度跟随)

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF实现仪表盘(刻度跟随)相关的知识,希望对你有一定的参考价值。

 WPF开发者QQ群: 340500857  | 微信群 -> 进入公众号主页 加入组织

 前言,接着上一篇圆形进度条。

欢迎转发、分享、点赞、在看,谢谢~。  

01

效果预览

效果预览(更多效果请下载源码体验):

02


代码如下

一、DashboardControl.cs 代码如下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using WpfDashboard.Models;


namespace WpfDashboard
{
    public class DashboardControl : ProgressBar
    {
        public DashboardControl()
        {
            this.ValueChanged += CircularProgressBar_ValueChanged;
        }


        void CircularProgressBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            DashboardControl bar = sender as DashboardControl;
            double currentAngle = bar.Angle;
            double targetAngle = e.NewValue / bar.Maximum * 180;
            Angle = targetAngle;
            if (ScaleArray == null)
                ArrayList();
            var count = Convert.ToInt32(Angle / (180 / ScaleNum));
            ScaleArray.ToList().ForEach(y =>
            {
                y.Background = Brushes.White;
            });


            Brush color = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FF19DCF0"));
            ScaleArray.Where(x => x.Index <= count).ToList().ForEach(y =>
            {


                y.Background = color;
            });
        }


        public double Angle
        {
            get { return (double)GetValue(AngleProperty); }
            set { SetValue(AngleProperty, value); }
        }


        public static readonly DependencyProperty AngleProperty =
            DependencyProperty.Register("Angle", typeof(double), typeof(DashboardControl), new PropertyMetadata(0.0));


        public IList<ScaleModel> ScaleArray
        {
            get { return (IList<ScaleModel>)GetValue(ScaleArrayProperty); }
            private set { SetValue(ScaleArrayProperty, value); }
        }


        public static readonly DependencyProperty ScaleArrayProperty =
            DependencyProperty.Register("ScaleArray", typeof(IList<ScaleModel>), typeof(DashboardControl), new PropertyMetadata(null));


        public int ScaleNum
        {
            get { return (int)GetValue(ScaleNumProperty); }
            set { SetValue(ScaleNumProperty, value); }
        }


        public static readonly DependencyProperty ScaleNumProperty =
            DependencyProperty.Register("ScaleNum", typeof(int), typeof(DashboardControl), new PropertyMetadata(18));
        void ArrayList()
        {
            List<ScaleModel> shortticks = new List<ScaleModel>();
            for (int i = 0; i < ScaleNum; i++)
            {
                shortticks.Add(new ScaleModel { Index = i, Background = Brushes.White });
            }
            this.ScaleArray = shortticks;
        }
    }
}


二、App.xaml 代码如下

<Application x:Class="WpfDashboard.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:ec="http://schemas.microsoft.com/expression/2010/controls" 
             xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
             xmlns:local="clr-namespace:WpfDashboard"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        
        <LinearGradientBrush x:Key="NormalBrush" EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FF164DA7"/>
            <GradientStop Color="#FF19DCF0" Offset="1"/>
        </LinearGradientBrush>
        <Style TargetType="local:DashboardControl">
            <Setter Property="Maximum" Value="100"/>
            <Setter Property="Background" Value="#252525"/>
            <Setter Property="Width" Value="200"/>
            <Setter Property="Height" Value="200"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:DashboardControl">
                        <Viewbox>
                            <Grid Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
                                    Background="{TemplateBinding Background}"
                                  RenderTransformOrigin="0.5,0.5">
                                <Grid.RenderTransform>
                                    <TransformGroup>
                                        <RotateTransform Angle="-90"/>
                                    </TransformGroup>
                                </Grid.RenderTransform>
                                <ed:Arc  ArcThickness="8" ArcThicknessUnit="Pixel" Fill="White"
                                         RenderTransformOrigin="0.5,0.5" 
                                         StartAngle="0"
                                         EndAngle="180"
                                         Stretch="None"
                                         Margin="10"/>
                                <ed:Arc x:Name="PART_PathBackground" Margin="24" ArcThickness="0" ArcThicknessUnit="Pixel"
                                        EndAngle="180"
                                        StartAngle="0"
                                        Stretch="None" />
                               
                                <ed:Arc ArcThickness="8" ArcThicknessUnit="Pixel" 
                                        Fill="{StaticResource NormalBrush}"
                                        StartAngle="0"
                                        EndAngle="{Binding Angle, RelativeSource={RelativeSource FindAncestor, AncestorType=ProgressBar}}"
                                        Stretch="None" 
                                        Margin="10"/>


                                <ec:PathListBox IsHitTestVisible="False"
                            ItemsSource="{Binding ScaleArray,RelativeSource={RelativeSource FindAncestor,AncestorType=ProgressBar}}">
                                    <ec:PathListBox.ItemTemplate>
                                        <DataTemplate>
                                            <Border Width="2" Height="8" Background="{Binding Background}" SnapsToDevicePixels="True"
                                    UseLayoutRounding="True" />
                                        </DataTemplate>
                                    </ec:PathListBox.ItemTemplate>
                                    <ec:PathListBox.LayoutPaths>
                                        <ec:LayoutPath Distribution="Even" Orientation="OrientToPath"
                                       SourceElement="{Binding ElementName=PART_PathBackground}" />
                                    </ec:PathListBox.LayoutPaths>
                                </ec:PathListBox>
                                <Border RenderTransformOrigin="0.5,0.5" Margin="30,0,0,0">
                                    <Border.RenderTransform>
                                        <TransformGroup>
                                            <RotateTransform Angle="90"/>
                                        </TransformGroup>
                                    </Border.RenderTransform>
                                    <TextBlock Foreground="{StaticResource NormalBrush}"
                                               FontSize="40"
                                               HorizontalAlignment="Center" VerticalAlignment="Center"
                                               Text="{Binding Path=Value, StringFormat={}{0}%, 
                                                    RelativeSource={RelativeSource TemplatedParent}}"
                                               FontWeight="Bold" FontFamily="Agency FB"/>
                                </Border>


                            </Grid>
                        </Viewbox>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
</Style>
    </Application.Resources>
</Application>


三、MainWindow.xaml 代码如下

<Window x:Class="WpfDashboard.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfDashboard"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <StackPanel VerticalAlignment="Center">
            <local:DashboardControl Value="{Binding ElementName=CirularSlider,Path=Value}"/>
            <Slider Minimum="0" Maximum="100" Margin="0,10"
                    x:Name="CirularSlider" IsSnapToTickEnabled="True"
                    VerticalAlignment="Center" Value="10" Width="220"/>
        </StackPanel>
    </Grid>
</Window>


源码地址

github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua

Github:https://github.com/yanjinhuagood

出处:https://www.cnblogs.com/yanjinhua

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

转载请著名作者 出处 https://github.com/yanjinhuagood

以上是关于WPF实现仪表盘(刻度跟随)的主要内容,如果未能解决你的问题,请参考以下文章

WPF 仪表盘 刻度盘 动态 加载中 开源

离谱的 CSS!从表盘刻度到艺术剪纸

WPF实现飞控姿态仪表盘控件Attitude dashboard

WPF实现飞控姿态仪表盘控件Attitude dashboard

在 WPF 中向鼠标旋转图形(如模拟表盘)

离谱的 CSS!从表盘刻度到剪纸艺术