Loading

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

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

每日一笑

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

前言 

      需要实现仪表盘。

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

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

一、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开发者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

posted @ 2021-07-15 14:58  驚鏵  阅读(1211)  评论(4编辑  收藏  举报