[WPF自定义控件库] 模仿UWP的ProgressRing
1. 为什么需要ProgressRing
在Windows 10中ProgressRing十分常见,而且十分好用。它还支持自适应尺寸,在紧凑的地方使用ProgressRing会给UI增色不少,而且不会显得格格不入:
那为什么不使用ProgressBar?其中一个原因是ProgressBar功能太多,而我很多时候只需要一个简单的显示正在等待的元素,另一个原因是条状的ProgressBar在紧凑的地方不好看,所以才需要结构相对简单的ProgressRing。
2. 基本结构
然后运行效果这样:
4. 自适应大小#
为了让ProgressRing中各个Ellipse都可以自适应大小,ProgressRing提供了一个TemplateSettings
属性,类型为TemplateSettingValues
,它里面包含以下记个依赖属性:
public double MaxSideLength { get { return (double)GetValue(MaxSideLengthProperty); } set { SetValue(MaxSideLengthProperty, value); } } public double EllipseDiameter { get { return (double)GetValue(EllipseDiameterProperty); } set { SetValue(EllipseDiameterProperty, value); } } public Thickness EllipseOffset { get { return (Thickness)GetValue(EllipseOffsetProperty); } set { SetValue(EllipseOffsetProperty, value); } }
XAML中的元素大小及布局绑定到这些属性:
<Grid x:Name="Ring" Background="{TemplateBinding Background}" MaxWidth="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.MaxSideLength}" MaxHeight="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.MaxSideLength}" Visibility="Collapsed" RenderTransformOrigin=".5,.5" FlowDirection="LeftToRight"> <Canvas RenderTransformOrigin=".5,.5"> <Canvas.RenderTransform> <RotateTransform x:Name="E1R" /> </Canvas.RenderTransform> <Ellipse x:Name="E1" Style="{StaticResource ProgressRingEllipseStyle}" Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}" Height="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseDiameter}" Margin="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.EllipseOffset}" Fill="{TemplateBinding Foreground}" /> </Canvas>
每当ProgressRing调用