之前看公司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("")); 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 = * bl;
DisPlayValue = (bl * ).ToString(CultureInfo.InvariantCulture);
}
}
} }

美中不足的是:

1、大小是我写死了的,因为里面那个水波是用path 写的 是个固定的

2、仔细看 中间有条白色的线(等有时间在解决吧)

学习到的知识:

1、学会用贝塞尔曲线,和它的动画

2、学会了Clip剪裁

3、看大佬的文章果然受益匪浅

附:解决有一条白线的问题

将水波纹进度条的 边线设置为0,代码为:

<Path SnapsToDevicePixels="True"
Fill="{Binding WavePorgressBarColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
Stroke="{Binding WavePorgressBarColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
StrokeThickness="0">
<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 SnapsToDevicePixels="True" Height="{Binding WaveProgressHeight,UpdateSourceTrigger=PropertyChanged}" Fill="{Binding WavePorgressBarColor,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>

将此代码直接覆盖 原有代码即可(StackPanel 中的那两个控件)

附源码:https://github.com/t115liyanpeng/WaveProgress

wpf 水波进度条 用户控件的更多相关文章

  1. .NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐)

    微信公众号:Dotnet9,网站:Dotnet9,问题或建议:请网站留言, 如果对您有所帮助:欢迎赞赏. .NET CORE(C#) WPF 方便的实现用户控件切换(祝大家新年快乐) 快到2020年了 ...

  2. 在wpf窗体上添加用户控件

    1.引用用户控件的命名控件 xmlns:my="clr-namespace:WpfApplicationDemo.Control" 2.把用户控件添加到窗体中 <my:Use ...

  3. wpf研究之道-ProgressBar(进度条)控件

    ProgressBar控件,非常有用.它在什么情况下有用呢?如何使用?带着这两个问题,我们探讨下. 如果程序需要很长时间来运行,用户在不知道的情况下,以为程序已经"卡死"了,没有响 ...

  4. JS实现 进度条 不用控件

    demo1 <html> <head> <title>进度条</title> <style type="text/css"&g ...

  5. WPF MVVM 用户控件完成分页

    项目中经常会有分页查询的情况,在WPF中我们可以通过用户控件完成分页 一下为分页控件的页面代码, <UserControl x:Class="Foundation.UCtrl.Next ...

  6. 浅尝辄止WPF自定义用户控件(实现颜色调制器)

    主要利用用户控件实现一个自定义的颜色调制控件,实现一个小小的功能,具体实现界面如下. 首先自己新建一个wpf的用户控件类,我就放在我的wpf项目的一个文件夹下面,因为是一个很小的东西,所以就没有用mv ...

  7. 【WPF学习】第六十四章 构建基本的用户控件

    创建一个简单用户控件是开始自定义控件的好方法.本章主要介绍创建一个基本的颜色拾取器.接下来分析如何将这个控件分解成功能更强大的基于模板的控件. 创建基本的颜色拾取器很容易.然而,创建自定义颜色拾取器仍 ...

  8. WPF自定义控件(五)の用户控件(完结)

    用户控件,WPF中是继承自UserControl的控件,我们可以在里面融合我们的业务逻辑. 示例:(一个厌恶选择的用户控件) 后端: using iMicClassBase; using iMicCl ...

  9. WPF 用户控件嵌入网页

    WPF使用用户控件嵌入网页,直接使用WebBrowser或Frame会产生报错,报错信息如下: 1.使用WebBrowser,<WebBrowser Source="http://19 ...

随机推荐

  1. python range用法

    1. range(n) 相当于枚举 从0<=i<n的整数 增量为1 for i in range(4): print(i) 结果:0 1 2 3 2. range(5,10) 相当于枚举 ...

  2. anaconda的源配置的坑

    anaconda是一个python的科学计算的包集合,它提供了一个非常好用的包管理器 conda,类似于pip. 为了速度(不仅为了速度,没有清华源你就被墙了,速度为0),我们使用清华源: 在类uni ...

  3. hdfs结构

    hdfs文件系统主要由四部分组成:client客户端.namenode.datanode.secondary namenode. client:1.分割文件成block.   2.与namenode交 ...

  4. syslog、日志服务器安装、卸载详解、如何安装和卸载EventLog Analyzer

  5. day13作业—(登录注册)

    2.写一个函数完成三次登陆功能: 用户的用户名密码从一个文件register中取出. register文件包含多个用户名,密码,用户名密码通过|隔开,每个人的用户名密码占用文件中一行. 完成三次验证, ...

  6. yum 安装报错:Could not retrieve mirrorlist http://mirrorlist.centos.org/?release=7&arch=x86_64&repo=os&infra=stock error was 14: curl#6 - "Could not resolve host: mirrorlist.centos.org; Unknown error"

    [root@venn09 ~]# yum install -y vim Loaded plugins: fastestmirror Could not retrieve mirrorlist http ...

  7. 关于流量升高导致TIME_WAIT增加,MySQL连接大量失败的问题

    有个应用就是每次都会去查一个接口,接口返回用户的信息数据,从而展现不同的页面效果.大致流程如下 应用APP(电信)-> memcache ->电信custom接口 ->master- ...

  8. WebSocket 处理事件

    WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 W ...

  9. Spring boot自动设置包依赖,根本不用记,

    maven有和多依赖包,每次搭建都很麻烦,其实IDE ,有个小技巧,就是如图所示,你给需要的技术,加入进去,自动就会生成包和相关依赖,根本无需自己配置

  10. DOM中的事件对象和IE事件对象

    DOM中的事件对象 IE事件对象 属性/方法 类型 读/写 说明 属性/方法 类型 读/写 说明  bubles Boolean 只读  表明事件是否冒泡  cancleBubble Boolean ...