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

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 自定义绕圈进度条的更多相关文章

  1. WPF 自定义绕圈进度条(转)

    在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码: 1.控件界面 <UserControl x:Class="ProgressBarControl&quo ...

  2. WPF 绕圈进度条(二)

    一 以前的方案 以前写过一个圆点绕圈的进度条,根据参数圆点个数和参数每次旋转角度,主要是在cs文件中动态添加圆点,通过后台定时器,动态设置角度后用正弦余弦计算(x,y)的位置. 此方案优点:动态添加L ...

  3. WPF 绕圈进度条(一)

    在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码: 1.控件界面 <UserControl x:Class="ProgressBarControl&quo ...

  4. WPF 简单的绕圈进度条(无cs代码)

    方案: 图标位置不变化的情况下设置透明度实现 代码: <Window x:Class="WpfApp1.MainWindow" xmlns="http://sche ...

  5. Android简易实战教程--第十七话《自定义彩色环形进度条》

    转载请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203533   点击打开链接 在Android初级教程里面,介绍了shape用法 ...

  6. WPF实现斜纹圆角进度条样式

    原文:WPF实现斜纹圆角进度条样式 运行效果: 进度条样式: <!--进度条样式--> <LinearGradientBrush x:Key="ProgressBar.Pr ...

  7. Android零基础入门第52节:自定义酷炫进度条

    原文:Android零基础入门第52节:自定义酷炫进度条 Android系统默认的ProgressBar往往都不能满足实际开发需要,一般都会开发者自定义ProgressBar. 在Android开发中 ...

  8. Android自定义圆角矩形进度条2

    效果图: 或 方法讲解: (1)invalidate()方法 invalidate()是用来刷新View的,必须是在UI线程中进行工作.比如在修改某个view的显示时, 调用invalidate()才 ...

  9. android 开发-自定义多节点进度条显示

    看效果图: 里面的线段颜色和节点图标都是可以自定义的. main.xml <RelativeLayout xmlns:android="http://schemas.android.c ...

随机推荐

  1. MathType应用:批量改变公式格式

    首先要安装好mathtype,一般装好后mathtype会嵌入到word里去(黄色和粉红的部分是今天的主角) 然后可以用带insert开头的选项(黄色部分)添加公式,但是添加公式后可能出现一下情况,即 ...

  2. Latex学习笔记-序

    在写论文的过程中自学了$\LaTeX$, 想总结一下使用心得.刚开始整理了一下发现非常之乱,不知这么多零碎的知识该如何整理的有条理点,至少以后用到还能翻翻自己博客.这次写作论文图省劲用了IEEE的模板 ...

  3. SQL Server中smalldatetime的日期范围为何是[1900-01-01,2079-06-06]

    本文目录列表: 1.SQL Server中的基准日期 2.smalldatetime的日期范围 3.smalldatetime的日期范围和无符号2字节整数的关系 4.总结语 5.参考清单列表   SQ ...

  4. Rafy 领域实体框架演示(3) - 快速使用 C/S 架构部署

    本系列演示如何使用 Rafy 领域实体框架快速转换一个传统的三层应用程序,并展示转换完成后,Rafy 带来的新功能. <福利到!Rafy(原OEA)领域实体框架 2.22.2067 发布!> ...

  5. 图片全部加载完成之后再显示页面ui,公司项目里用上,自己写的几行代码

    说明: -----onload事件   这里我并没有考虑ie的兼容性 因为项目是移动端的: -----求大神指正~ -----自己测试正常 页面没加载完之前会有一个提示 /************** ...

  6. .NET设计模式(1):1.1 单例模式(Singleton Pattern)

    概述 单例模式就是保证在整个应用程序的生命周期中,在任何时刻,被指定的类只有一个实例,并为客户程序提供一个获取该实例的全局访问点. 单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单 ...

  7. WPF资源使用

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...

  8. jQuery鼠标滚动垂直全屏切换代码

    体验效果:http://hovertree.com/texiao/jquery/68/ 源码下载:http://hovertree.com/h/bjaf/f643upc4.htm 代码如下: < ...

  9. 未能解析此远程名称: 'api.ucpaas.com'

     未能解析此远程名称: 'api.ucpaas.com'  这个问题的原因不是云之讯,而是(我用的是阿里云)云服务器的DNS解析的问题 或者是云服务器后台的安全组规则的问题, 应该把内网入方向和内网出 ...

  10. 如何实现在PHP中调用JAVA

    详细说明:http://php.662p.com/thread-275-1-1.html PHP与JAVA JAVA是个非常强大的编程利器,它的扩展库也是非常的有用,这篇教程,主要讲述怎样使用PHP调 ...