之前看公司web前端做了个 圆形的水波纹 进度条,就想用wpf 做一个,奈何自己太菜 一直做不出来,在看过 “普通的地球人” 的 “
WPF实现三星手机充电界面 博客之后 我也来照葫芦画个瓢。
废话不多说 先贴一下效果图
虽然样子 low 了些 但是基本满足我的需求了,下面是代码
前端
<UserControl x:Class="WaveProgress.UserControl.WaveProgressControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WaveProgress.UserControl" mc:Ignorable="d" Height="150" Width="150" x:Name="wave_control"> <UserControl.Resources> <Storyboard x:Key="WaterStoryboard"> <PointAnimation Storyboard.TargetName="bs_Water" DesiredFrameRate="20" Storyboard.TargetProperty="Point1" From="90,60" To="90,90" Duration="00:00:2" AutoReverse="True" RepeatBehavior="Forever"></PointAnimation> <PointAnimation Storyboard.TargetName="bs_Water" DesiredFrameRate="20" Storyboard.TargetProperty="Point2" From="100,110" To="100,95" Duration="00:00:1.8" AutoReverse="True" RepeatBehavior="Forever"></PointAnimation> </Storyboard> </UserControl.Resources> <Grid Width="{Binding ElementName=wave_control,Path=Width}" Height="{Binding ElementName=wave_control,Path=Height}" Background="{Binding WaveProgressBackground,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <Grid.Clip> <EllipseGeometry Center="75,75" RadiusX="75" RadiusY="75" ></EllipseGeometry> </Grid.Clip> <StackPanel Width="150" VerticalAlignment="Bottom"> <Path Fill="{Binding WavePorgressBarColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" > <Path.Data> <PathGeometry FillRule="EvenOdd" > <PathFigure StartPoint="0,90" > <BezierSegment x:Name="bs_Water" Point1="90,60" Point2="100,110" Point3="150,90"></BezierSegment> <PolyLineSegment Points="150,100 0,100"></PolyLineSegment> </PathFigure> </PathGeometry> </Path.Data> <Path.Triggers> <EventTrigger RoutedEvent="Path.Loaded"> <BeginStoryboard Storyboard="{StaticResource WaterStoryboard}"></BeginStoryboard> </EventTrigger> </Path.Triggers> </Path> <Rectangle Height="{Binding WaveProgressHeight,UpdateSourceTrigger=PropertyChanged}" Fill="{Binding WavePorgressBarColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> </StackPanel> <Ellipse VerticalAlignment="Bottom" Width="150" Height="150" Stroke="{Binding WaveBorderBrush,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Fill="Transparent" StrokeThickness="{Binding WaveBorderThickness,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="22" Foreground="{Binding TextColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> <Run Text="{Binding DisPlayValue,UpdateSourceTrigger=PropertyChanged}"></Run> <Run Text="%"></Run> </TextBlock> </Grid> </UserControl>
后台
using System.Globalization; using System.Windows; using System.Windows.Media; namespace WaveProgress.UserControl { /// <summary> /// WaveProgressControl.xaml 的交互逻辑 /// </summary> public partial class WaveProgressControl : System.Windows.Controls.UserControl { public WaveProgressControl() { InitializeComponent(); this.DataContext = this; } public static readonly DependencyProperty WaveProgressBackgroundProperty = DependencyProperty.Register( "WaveProgressBackground", typeof(SolidColorBrush), typeof(WaveProgressControl), new PropertyMetadata(Brushes.White)); /// <summary> /// 进度条背景色 /// </summary> public SolidColorBrush WaveProgressBackground { get { return (SolidColorBrush) GetValue(WaveProgressBackgroundProperty); } set { SetValue(WaveProgressBackgroundProperty, value); } } public static readonly DependencyProperty WaveBorderBrushProperty = DependencyProperty.Register( "WaveBorderBrush", typeof(SolidColorBrush), typeof(WaveProgressControl), new PropertyMetadata(Brushes.Blue)); /// <summary> /// 边框颜色 /// </summary> public SolidColorBrush WaveBorderBrush { get { return (SolidColorBrush) GetValue(WaveBorderBrushProperty); } set { SetValue(WaveBorderBrushProperty, value); } } public static readonly DependencyProperty WaveBorderThicknessProperty = DependencyProperty.Register( "WaveBorderThickness", typeof(double), typeof(WaveProgressControl), new PropertyMetadata(2.0)); /// <summary> /// 边框粗细 /// </summary> public double WaveBorderThickness { get { return (double) GetValue(WaveBorderThicknessProperty); } set { SetValue(WaveBorderThicknessProperty, value); } } public static readonly DependencyProperty WavePorgressBarColorProperty = DependencyProperty.Register( "WavePorgressBarColor", typeof(SolidColorBrush), typeof(WaveProgressControl), new PropertyMetadata(Brushes.Red)); /// <summary> /// 进度条颜色 /// </summary> public SolidColorBrush WavePorgressBarColor { get { return (SolidColorBrush) GetValue(WavePorgressBarColorProperty); } set { SetValue(WavePorgressBarColorProperty, value); } } public static readonly DependencyProperty TextColorProperty = DependencyProperty.Register( "TextColor", typeof(SolidColorBrush), typeof(WaveProgressControl), new PropertyMetadata(Brushes.Black)); /// <summary> /// 文字颜色 /// </summary> public SolidColorBrush TextColor { get { return (SolidColorBrush) GetValue(TextColorProperty); } set { SetValue(TextColorProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( "Value", typeof(double), typeof(WaveProgressControl), new PropertyMetadata(default(double))); /// <summary> /// 当前进度 /// </summary> public double Value { get { return (double) GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register( "MaxValue", typeof(double), typeof(WaveProgressControl), new PropertyMetadata(default(double))); public double MaxValue { get { return (double) GetValue(MaxValueProperty); } set { SetValue(MaxValueProperty, value); } } public static readonly DependencyProperty DisPlayValueProperty = DependencyProperty.Register( "DisPlayValue", typeof(string), typeof(WaveProgressControl), new PropertyMetadata("0")); public string DisPlayValue { get { return (string) GetValue(DisPlayValueProperty); } set { SetValue(DisPlayValueProperty, value); } } public static readonly DependencyProperty WaveProgressHeightProperty = DependencyProperty.Register( "WaveProgressHeight", typeof(double), typeof(WaveProgressControl), new PropertyMetadata(default(double))); /// <summary> /// 次属性不要手动设置 /// </summary> public double WaveProgressHeight { get { return (double) GetValue(WaveProgressHeightProperty); } set { SetValue(WaveProgressHeightProperty, value); } } protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) { base.OnPropertyChanged(e); if (e.Property == ValueProperty) { double bl = Value / MaxValue; WaveProgressHeight = 140 * bl; DisPlayValue = (bl * 100).ToString(CultureInfo.InvariantCulture); } } } }
美中不足的是:
1、大小是我写死了的,因为里面那个水波是用path 写的 是个固定的
2、仔细看 中间有条白色的线(等有时间在解决吧)
学习到的知识:
1、学会用贝塞尔曲线,和它的动画
2、学会了Clip剪裁
3、看大佬的文章果然受益匪浅
原文地址:https://www.cnblogs.com/wuyaxiansheng/p/10478574.html
时间: 2024-10-10 05:42:54