WPF 绕圈进度条(一)
在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码:

1、控件界面
<UserControl x:Class="ProgressBarControl"
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"
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="300"
Background="Gray" Loaded="ProgressBarControl_OnLoaded"> <Grid>
<Grid.Resources>
<Style TargetType="Ellipse">
<Setter Property="Height" Value="{Binding EclipseSize}"></Setter>
<Setter Property="Width" Value="{Binding EclipseSize}"></Setter>
<Setter Property="Stretch" Value="Fill"></Setter>
<!--设置圆的颜色-->
<Setter Property="Fill" Value="White"></Setter>
</Style>
</Grid.Resources>
<StackPanel HorizontalAlignment="Center"
VerticalAlignment="Center">
<Viewbox Width="{Binding ViewBoxSize}" Height="{Binding ViewBoxSize}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid x:Name="LayoutRoot"
Background="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<!--此处有canvas的加载和卸载事件-->
<Canvas x:Name="ProgressBarCanvas" RenderTransformOrigin="0.5,0.5"
HorizontalAlignment="Center"
VerticalAlignment="Center" Width="{Binding CanvasSize}"
Height="{Binding CanvasSize}" Loaded="HandleLoaded"
Unloaded="HandleUnloaded" >
<!--画圆-->
<Canvas.RenderTransform>
<RotateTransform x:Name="SpinnerRotate" Angle="0" />
</Canvas.RenderTransform>
</Canvas>
</Grid>
</Viewbox>
</StackPanel>
</Grid>
</UserControl>
2、控件后台逻辑:
控件后台:
/// <summary>
/// 进度条
/// </summary>
public partial class ProgressBarControl : UserControl
{
//集成到按指定时间间隔和指定优先级处理的 System.Windows.Threading.Dispatcher 队列中的计时器。
private DispatcherTimer animationTimer;
private ProgressBarDataModel _dataModel;
private int index = ;
#region 构造方法与加载
/// <summary>
/// 构造方法
/// </summary>
public ProgressBarControl()
{
InitializeComponent(); }
/// <summary>
/// 加载后刷新
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ProgressBarControl_OnLoaded(object sender, RoutedEventArgs e)
{
animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher);
//指定时间间隔
animationTimer.Interval = new TimeSpan(, , , , TimeSpan);
if (EllipseCount < )
{
EllipseCount = ;
}
for (int i = ; i < EllipseCount; i++)
{
ProgressBarCanvas.Children.Add(new Ellipse());
}
var dataModel = new ProgressBarDataModel()
{
CanvasSize = CanvasSize,
EclipseSize = EllipseSize
};
_dataModel = dataModel;
this.DataContext = dataModel;
}
#endregion #region 属性
/// <summary>
/// 获取或设置圆圈数量
/// 默认12
/// </summary>
public double EllipseCount
{
get { return (double)GetValue(EllipseCountProperty); }
set { SetValue(EllipseCountProperty, value); }
}
public static readonly DependencyProperty EllipseCountProperty =
DependencyProperty.Register("EllipseCount", typeof(double), typeof(ProgressBarControl),
new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary>
/// 获取或设置圆圈大小
/// 默认10
/// </summary>
public double EllipseSize
{
get { return (double)GetValue(EllipseSizeProperty); }
set { SetValue(EllipseSizeProperty, value); }
}
public static readonly DependencyProperty EllipseSizeProperty =
DependencyProperty.Register("EllipseSize", typeof(double), typeof(ProgressBarControl),
new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary>
/// 获取或设置面板大小
/// 默认80
/// </summary>
public double CanvasSize
{
get { return (double)GetValue(CanvasSizeProperty); }
set { SetValue(CanvasSizeProperty, value); }
}
public static readonly DependencyProperty CanvasSizeProperty =
DependencyProperty.Register("CanvasSize", typeof(double), typeof(ProgressBarControl),
new FrameworkPropertyMetadata(80.0, FrameworkPropertyMetadataOptions.AffectsRender)); /// <summary>
/// 获取或设置每次旋转角度
/// 默认10.0
/// </summary>
public double StepAngle
{
get { return (double)GetValue(StepAngleProperty); }
set { SetValue(StepAngleProperty, value); }
} public static readonly DependencyProperty StepAngleProperty =
DependencyProperty.Register("StepAngle", typeof(double), typeof(ProgressBarControl),
new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// 获取或设置每次旋转间隔时间(毫秒)
/// 默认100毫秒
/// </summary>
public int TimeSpan
{
get { return (int)GetValue(TimeSpanProperty); }
set { SetValue(TimeSpanProperty, value); }
}
public static readonly DependencyProperty TimeSpanProperty =
DependencyProperty.Register("TimeSpan", typeof(int), typeof(ProgressBarControl),
new FrameworkPropertyMetadata(, FrameworkPropertyMetadataOptions.AffectsRender)); #endregion #region 方法
/// <summary>
/// Canvas加载
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleLoaded(object sender, RoutedEventArgs e)
{
//设置设置圆的位置和旋转角度
SetEclipsePosition(_dataModel);
//DesignerProperties 提供用于与设计器进行通信的附加属性。
if (!DesignerProperties.GetIsInDesignMode(this))
{
if (this.Visibility == System.Windows.Visibility.Visible)
{
//超过计时器间隔时发生。
animationTimer.Tick += HandleAnimationTick;
animationTimer.Start();
}
}
} /// <summary>
/// 设置圆的位置和旋转角度
/// </summary>
private void SetEclipsePosition(ProgressBarDataModel dataModel)
{
//圆周长就是:C = π * d 或者C=2*π*r(其中d是圆的直径,r是圆的半径)
double r =dataModel.R; var children=ProgressBarCanvas.Children;
int count = children.Count;
double step = (Math.PI * ) / count; //根据圆中正弦、余弦计算距离
int index = ;
foreach (var element in children)
{
var ellipse = element as Ellipse;
//透明度
var opacity = Convert.ToDouble(index)/(count - );
ellipse.SetValue(UIElement.OpacityProperty, opacity<0.05?0.05:opacity);
//距离
double left = r + Math.Sin(step*index)*r;
ellipse.SetValue(Canvas.LeftProperty,left);
double top = r - Math.Cos(step*index)*r;
ellipse.SetValue(Canvas.TopProperty, top); index++;
}
} /// <summary>
/// Canvas卸载时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleUnloaded(object sender, RoutedEventArgs e)
{
animationTimer.Stop();
//除去委托
animationTimer.Tick -= HandleAnimationTick;
} /// <summary>
/// 超过计时器间隔时发生。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void HandleAnimationTick(object sender, EventArgs e)
{
//设置旋转角度
SpinnerRotate.Angle = (SpinnerRotate.Angle + StepAngle) % ;
}
#endregion
}
数据Model类:
/// <summary>
/// 进度条Model类
/// </summary>
public class ProgressBarDataModel
{
public double EclipseSize { get; set; }
public double CanvasSize { get; set; }
public double ViewBoxSize
{
get
{
double length = Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize);
return length;
}
}
public double EclipseLeftLength
{
get
{
double length = Convert.ToDouble(CanvasSize) / 2;
return length;
}
}
public double R
{
get
{
double length = (Convert.ToDouble(CanvasSize) - Convert.ToDouble(EclipseSize)) / 2;
return length;
}
}
}
3、取用控件
<control:ProgressBarControl CanvasSize="100" EllipseCount="10" EllipseSize="10" StepAngle="36" TimeSpan="60"/>
WPF 绕圈进度条(一)的更多相关文章
- WPF 绕圈进度条(二)
一 以前的方案 以前写过一个圆点绕圈的进度条,根据参数圆点个数和参数每次旋转角度,主要是在cs文件中动态添加圆点,通过后台定时器,动态设置角度后用正弦余弦计算(x,y)的位置. 此方案优点:动态添加L ...
- WPF 自定义绕圈进度条
在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码: 1.控件界面 <UserControl x:Class="ProgressBarControl&quo ...
- WPF 自定义绕圈进度条(转)
在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码: 1.控件界面 <UserControl x:Class="ProgressBarControl&quo ...
- WPF 简单的绕圈进度条(无cs代码)
方案: 图标位置不变化的情况下设置透明度实现 代码: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...
- WPF Canvas实现进度条
原文:WPF Canvas实现进度条 先看效果图: 思路: 一个Canvas做背景,一个Canvas用来显示进度,图片放在显示进度的Canvas中,靠右设置为图片本身宽度一半的距离,视觉上实现以图片中 ...
- WPF自定义控件第一 - 进度条控件
本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...
- WPF 实现圆形进度条
项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...
- WPF好看的进度条实现浅谈(效果有点类似VS2012安装界面)
为了界面友好,一般的操作时间较长时,都需要增加进度条提示.由于WPF自带的进度条其实不怎么好看,而且没啥视觉效果.后来,装VS2012时,发现安装过程中进度条效果不错,于是上网查了资料.学习了Mode ...
- 使用线程新建WPF窗体(公用进度条窗体)
使用线程新建窗体 项目中需要一个公用的进度条窗体.大家知道在wpf中,有两个线程,一个是UI线程,另一个是监听线程(一直监听用户的输入).如果我们后台有阻塞UI线程的计算存在,那么界面上的比如进度条什 ...
随机推荐
- Failed to start end point associated with ProtocolHandler ["http-nio-8080"]
Spring boot运行项目报错,说明8080端口被占用 此时任务管理器结束javax程序即可.
- JavaScript(变量、作用域和内存问题)
JavaScript是一个变量松散型的语言.(不像Java一样强类型语言.) JavaScript变量包括两种:基本类型(简单的数据段)和引用类型(对象). 一.基本数据类型(5种) Undefine ...
- maven项目(多模块)
在eclipse下构建maven项目,该项目由多个子模块组成. 1.创建一个父项目 NEW -->project-->maven-->maven Project,点击下一步,进入ne ...
- [转] kaldi中FST的可视化-以yesno为例
http://blog.csdn.net/u013677156/article/details/77893661 1.kaldi解码过程 kaldi识别解码一段语音的过程是:首先提取特征,然后过声学模 ...
- 致我们再也回不去的 Github ...
本文原文来自公众号 stormzhang,原作者自称“二流学校毕业.非科班出身.从 0 自学编程到现在的「段子张」”. 1.前言 相信大家都知道了,微软已确认要收购 GitHub 了,Github ...
- Eclipse 在高分辨率4K显示器下图标按钮过小
买了LG的4K显示器,发现由于分辨率太高,导致好多软件和网站都没进行高分辨率适配,显示比较小,缩放会使好多软件都显示错位.Eclipse就是其中之一. 网上搜了下解决方案如下: 原理 高DPI Win ...
- ExternalException (0x80004005): 无法执行程序
今天更新系统上传到阿里云服务器,报错如下: “/”应用程序中的服务器错误. 组策略阻止了这个程序.要获取详细信息,请与系统管理员联系. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆 ...
- deque源码4(deque元素操作:pop_back、pop_front、clear、erase、insert)
deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...
- cp2102 驱动 win7x64 -2018
试了好多种网上的驱动,都不行,要么是报错要么是安装没反应 之后意外遇见驱动官网?里面真全 url:https://www.silabs.com/products/development-tools/s ...
- [NewLife.XCode]增删改查入门
NewLife.XCode是一个有10多年历史的开源数据中间件,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode. 整个系列教程会大量结合示例代码和运行日志来进行深入分析,蕴含 ...