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

  • A+
所属分类:.NET技术
摘要

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

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

每日一笑

            刚和另一位摸鱼大户同事聊天,说起业余爱好。我:“我下班就看看电影打打游戏,你呢?”同事:“帮人做网站挣点外快,另外最近我目前在做一个区块链的创业项目,已经占我总收入10%了 。我有时候回复工作消息慢就是在搞这个。”感觉被背叛了,原来只有我是傻呵呵地真摸鱼。

前言 

      需要实现仪表盘。

欢迎转发、分享、点赞,谢谢大家~。  

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

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

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

更多教程欢迎关注微信公众号:

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

WPF开发者QQ群: 340500857 

blogs: https://www.cnblogs.com/yanjinhua/p/14345136.html

源码Github:https://github.com/yanjinhuagood/WPFDevelopers.git

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