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