使用WPF怎么编写一个转圈进度条效果
作者
使用WPF怎么编写一个转圈进度条效果?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
1、控件界面
<UserControlx: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>
<StyleTargetType="Ellipse">
<SetterProperty="Height"Value="{BindingEclipseSize}"></Setter>
<SetterProperty="Width"Value="{BindingEclipseSize}"></Setter>
<SetterProperty="Stretch"Value="Fill"></Setter>
<!--设置圆的颜色-->
<SetterProperty="Fill"Value="White"></Setter>
</Style>
</Grid.Resources>
<StackPanelHorizontalAlignment="Center"
VerticalAlignment="Center">
<ViewboxWidth="{BindingViewBoxSize}"Height="{BindingViewBoxSize}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Gridx:Name="LayoutRoot"
Background="Transparent"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<!--此处有canvas的加载和卸载事件-->
<Canvasx:Name="ProgressBarCanvas"RenderTransformOrigin="0.5,0.5"
HorizontalAlignment="Center"
VerticalAlignment="Center"Width="{BindingCanvasSize}"
Height="{BindingCanvasSize}"Loaded="HandleLoaded"
Unloaded="HandleUnloaded">
<!--画圆-->
<Canvas.RenderTransform>
<RotateTransformx:Name="SpinnerRotate"Angle="0"/>
</Canvas.RenderTransform>
</Canvas>
</Grid>
</Viewbox>
</StackPanel>
</Grid>
</UserControl>2、控件后台逻辑:
控件后台:
///<summary>
///进度条
///</summary>
publicpartialclassProgressBarControl:UserControl
{
//集成到按指定时间间隔和指定优先级处理的System.Windows.Threading.Dispatcher队列中的计时器。
privateDispatcherTimeranimationTimer;
privateProgressBarDataModel_dataModel;
privateintindex=0;
#region构造方法与加载
///<summary>
///构造方法
///</summary>
publicProgressBarControl()
{
InitializeComponent();
}
///<summary>
///加载后刷新
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
privatevoidProgressBarControl_OnLoaded(objectsender,RoutedEventArgse)
{
animationTimer=newDispatcherTimer(DispatcherPriority.ContextIdle,Dispatcher);
//指定时间间隔
animationTimer.Interval=newTimeSpan(0,0,0,0,TimeSpan);
if(EllipseCount<1)
{
EllipseCount=12;
}
for(inti=0;i<EllipseCount;i++)
{
ProgressBarCanvas.Children.Add(newEllipse());
}
vardataModel=newProgressBarDataModel()
{
CanvasSize=CanvasSize,
EclipseSize=EllipseSize
};
_dataModel=dataModel;
this.DataContext=dataModel;
}
#endregion
#region属性
///<summary>
///获取或设置圆圈数量
///默认12
///</summary>
publicdoubleEllipseCount
{
get{return(double)GetValue(EllipseCountProperty);}
set{SetValue(EllipseCountProperty,value);}
}
publicstaticreadonlyDependencyPropertyEllipseCountProperty=
DependencyProperty.Register("EllipseCount",typeof(double),typeof(ProgressBarControl),
newFrameworkPropertyMetadata(10.0,FrameworkPropertyMetadataOptions.AffectsRender));
///<summary>
///获取或设置圆圈大小
///默认10
///</summary>
publicdoubleEllipseSize
{
get{return(double)GetValue(EllipseSizeProperty);}
set{SetValue(EllipseSizeProperty,value);}
}
publicstaticreadonlyDependencyPropertyEllipseSizeProperty=
DependencyProperty.Register("EllipseSize",typeof(double),typeof(ProgressBarControl),
newFrameworkPropertyMetadata(10.0,FrameworkPropertyMetadataOptions.AffectsRender));
///<summary>
///获取或设置面板大小
///默认80
///</summary>
publicdoubleCanvasSize
{
get{return(double)GetValue(CanvasSizeProperty);}
set{SetValue(CanvasSizeProperty,value);}
}
publicstaticreadonlyDependencyPropertyCanvasSizeProperty=
DependencyProperty.Register("CanvasSize",typeof(double),typeof(ProgressBarControl),
newFrameworkPropertyMetadata(80.0,FrameworkPropertyMetadataOptions.AffectsRender));
///<summary>
///获取或设置每次旋转角度
///默认10.0
///</summary>
publicdoubleStepAngle
{
get{return(double)GetValue(StepAngleProperty);}
set{SetValue(StepAngleProperty,value);}
}
publicstaticreadonlyDependencyPropertyStepAngleProperty=
DependencyProperty.Register("StepAngle",typeof(double),typeof(ProgressBarControl),
newFrameworkPropertyMetadata(10.0,FrameworkPropertyMetadataOptions.AffectsRender));
///<summary>
///获取或设置每次旋转间隔时间(毫秒)
///默认100毫秒
///</summary>
publicintTimeSpan
{
get{return(int)GetValue(TimeSpanProperty);}
set{SetValue(TimeSpanProperty,value);}
}
publicstaticreadonlyDependencyPropertyTimeSpanProperty=
DependencyProperty.Register("TimeSpan",typeof(int),typeof(ProgressBarControl),
newFrameworkPropertyMetadata(100,FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region方法
///<summary>
///Canvas加载
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
privatevoidHandleLoaded(objectsender,RoutedEventArgse)
{
//设置设置圆的位置和旋转角度
SetEclipsePosition(_dataModel);
//DesignerProperties提供用于与设计器进行通信的附加属性。
if(!DesignerProperties.GetIsInDesignMode(this))
{
if(this.Visibility==System.Windows.Visibility.Visible)
{
//超过计时器间隔时发生。
animationTimer.Tick+=HandleAnimationTick;
animationTimer.Start();
}
}
}
///<summary>
///设置圆的位置和旋转角度
///</summary>
privatevoidSetEclipsePosition(ProgressBarDataModeldataModel)
{
//圆周长就是:C=π*d或者C=2*π*r(其中d是圆的直径,r是圆的半径)
doubler=dataModel.R;
varchildren=ProgressBarCanvas.Children;
intcount=children.Count;
doublestep=(Math.PI*2)/count;
//根据圆中正弦、余弦计算距离
intindex=0;
foreach(varelementinchildren)
{
varellipse=elementasEllipse;
//透明度
varopacity=Convert.ToDouble(index)/(count-1);
ellipse.SetValue(UIElement.OpacityProperty,opacity<0.05?0.05:opacity);
//距离
doubleleft=r+Math.Sin(step*index)*r;
ellipse.SetValue(Canvas.LeftProperty,left);
doubletop=r-Math.Cos(step*index)*r;
ellipse.SetValue(Canvas.TopProperty,top);
index++;
}
}
///<summary>
///Canvas卸载时
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
privatevoidHandleUnloaded(objectsender,RoutedEventArgse)
{
animationTimer.Stop();
//除去委托
animationTimer.Tick-=HandleAnimationTick;
}
///<summary>
///超过计时器间隔时发生。
///</summary>
///<paramname="sender"></param>
///<paramname="e"></param>
privatevoidHandleAnimationTick(objectsender,EventArgse)
{
//设置旋转角度
SpinnerRotate.Angle=(SpinnerRotate.Angle+StepAngle)%360;
}
#endregion
}数据Model类:
///<summary>
///进度条Model类
///</summary>
publicclassProgressBarDataModel
{
publicdoubleEclipseSize{get;set;}
publicdoubleCanvasSize{get;set;}
publicdoubleViewBoxSize
{
get
{
doublelength=Convert.ToDouble(CanvasSize)-Convert.ToDouble(EclipseSize);
returnlength;
}
}
publicdoubleEclipseLeftLength
{
get
{
doublelength=Convert.ToDouble(CanvasSize)/2;
returnlength;
}
}
publicdoubleR
{
get
{
doublelength=(Convert.ToDouble(CanvasSize)-Convert.ToDouble(EclipseSize))/2;
returnlength;
}
}
}3、取用控件
<control:ProgressBarControlCanvasSize="100"EllipseCount="10"EllipseSize="10"StepAngle="36"TimeSpan="60"/>
看完上述内容,你们掌握使用WPF怎么编写一个转圈进度条效果的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注恰卡编程网行业资讯频道,感谢各位的阅读!
目录
推荐阅读
-
怎么为WPF框架Prism注册Nlog日志服务
怎么为WPF框架Prism注册Nlog日志服务这篇文章主要为大家展...
-
WPF框架Prism中导航Navigation怎么使用
WPF框架Prism中导航Navigation怎么使用这篇文章主要...
-
WPF怎么使用代码创建数据模板DataTemplate
WPF怎么使用代码创建数据模板DataTemplate这篇文章主要...
-
WPF中怎么自定义ProgressBar滚动条样式
本篇文章为大家展示了WPF中怎么自定义ProgressBar滚动条样式,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章...
-
WPF中InkCanvas基本操作方法的示例分析
这篇文章将为大家详细讲解有关WPF中InkCanvas基本操作方法的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅...
-
怎么用WPF实现微信公众号多客服功能
这篇文章给大家分享的是有关怎么用WPF实现微信公众号多客服功能的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看...
