【转】WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

一.前言

  申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等。

  本文主要内容:

  • ProcessBar自定义标准样式;
  • ProcessBar自定义环形进度样式;

二.ProcessBar标准样式

  效果图:

 

  ProcessBar的样式非常简单:  

复制代码
<!--ProgressBar Style-->
    <Style TargetType="ProgressBar" x:Key="SimpleProgressBar">
        <Setter Property="Background" Value="{StaticResource ControlBorderBrush}" />
        <Setter Property="Maximum" Value="1" />
        <Setter Property="Value" Value="0" />
        <Setter Property="Height" Value="10" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="Foreground" Value="{StaticResource FocusBorderBrush}" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="local:ControlAttachProperty.CornerRadius" Value="0" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="ProgressBar">
                    <Grid x:Name="Root" >
                        <Border x:Name="PART_Track" Background="{TemplateBinding Background}" 
                                CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                        <Border  x:Name="PART_Indicator" HorizontalAlignment="Left" Background="{TemplateBinding Foreground}" 
                                CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}"
                                SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="Orientation" Value="Vertical">
                            <Setter Property="LayoutTransform" TargetName="Root" >
                                <Setter.Value>
                                    <RotateTransform Angle="-90" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
复制代码

使用示例:  

<ProgressBar Margin="5" Value="{Binding Percent,Mode=OneWay}" Style="{StaticResource SimpleProgressBar}" x:Name="pro4"></ProgressBar>
<ProgressBar Margin="5" Value="{Binding Percent,Mode=OneWay}" Height="15" x:Name="pro5" Background="LightSteelBlue" Foreground="OrangeRed" 
  Style="{StaticResource SimpleProgressBar}"></ProgressBar>

三.ProcessBar环形进度样式

  效果图:

 

样式定义也比较简单:  

复制代码
<!--注意:该样式的ProgressBar的最大值为1,,BorderThickness控制环的大小-->
   <!--ed需要引用:xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"-->

    <Style x:Key="LoopProcessBar" TargetType="{x:Type ProgressBar}">
        <Setter Property="Background" Value="#C1D1DE"/>
        <Setter Property="Margin" Value="5"/>
        <Setter Property="Width" Value="300"/>
        <Setter Property="Height" Value="300"/>
        <Setter Property="BorderBrush" Value="BlueViolet"/>
        <Setter Property="BorderThickness" Value="60"/>
        <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
        <Setter Property="Maximum" Value="1"/>
        <Setter Property="Minimum" Value="0"/>
        <Setter Property="Value" Value="0"/>
        <Setter Property="IsTabStop" Value="False"/>
        <Setter Property="IsHitTestVisible" Value="False"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ProgressBar}">
                    <Viewbox Stretch="Uniform"  VerticalAlignment="Center" HorizontalAlignment="Center">
                        <Grid  Margin="{TemplateBinding Margin}" SnapsToDevicePixels="True" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" >
                            <!--背景环-->
                            <ed:Arc Margin="{TemplateBinding Margin}" Opacity="0.6" ArcThickness="{Binding Path=BorderThickness,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay,Converter={x:Static local:XConverter.ThicknessToDoubleConverter}}"
                                    StartAngle="0" Fill="{TemplateBinding Background}" EndAngle="360" Stretch="None" x:Name="arcOuter" />
                            <!--值-环-->
                            <ed:Arc Margin="{TemplateBinding Margin}" x:Name="arcValue" ArcThickness="{Binding Path=BorderThickness,RelativeSource={RelativeSource TemplatedParent},Mode=OneWay,Converter={x:Static local:XConverter.ThicknessToDoubleConverter}}"
                                    StartAngle="0" Fill="{TemplateBinding BorderBrush}" 
                                Stretch="None"  Panel.ZIndex="2"
                                EndAngle="{TemplateBinding Value, Converter={x:Static local:XConverter.PercentToAngleConverter}}" >
                            </ed:Arc>
                        </Grid>
                    </Viewbox>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
复制代码

上面样式中使用了两个转换器:

  • ThicknessToDoubleConverter:使用ProcessBar本身的属性BorderThickness设置环形宽度,把BorderThickness转换为环Arc宽度所需要的值;
  • PercentToAngleConverter:当前进度值转换为环Arc的角度值;

  这个地方有个小技巧,把常用的转换器声明为静态变量,XAML中以"x:Static"方式静态使用,这样使用的时候就方便多了,不用xaml中单独定义了。当然这样做也有弊端,因为静态变量本身的特点所决定的,不可滥用。 

复制代码
/// <summary>
   /// 百分比转换为角度值
   /// </summary>
   public class PercentToAngleConverter : IValueConverter
   {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           var percent = value.ToSafeString().ToDouble();
           if (percent >= 1) return 360.0D;
           return percent * 360;
       }
 
       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           throw new NotImplementedException();
       }
   }
 
   /// <summary>
   /// 获取Thickness固定值double
   /// </summary>
   public class ThicknessToDoubleConverter : IValueConverter
   {
       public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
       {
           var thickness = (Thickness)value;
           return thickness.Left;
       }
 
       public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
       {
           return DependencyProperty.UnsetValue;
       }
   }
复制代码

使用示例:  

<ProgressBar Style="{StaticResource LoopProcessBar}" Value="{Binding Percent,Mode=OneWay}"  x:Name="pro1" ></ProgressBar>

            <Grid Width="200" Height="200">
                <ProgressBar Style="{StaticResource LoopProcessBar}" Value="{Binding Percent,Mode=OneWay}" x:Name="pro2" Margin="0" Width="200" Height="200" BorderThickness="20" BorderBrush="#EF436F"/>
                <TextBlock FontSize="30" Text="{Binding Value,Mode=OneWay,ElementName=pro2,StringFormat={}{0:p1}}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
            </Grid>

            <ProgressBar Style="{StaticResource LoopProcessBar}" x:Name="pro3" Value="{Binding Percent,Mode=OneWay}" Width="100" Height="100" BorderThickness="10" BorderBrush="#EFBF0E"></ProgressBar>

 

原文地址:https://www.cnblogs.com/anding/p/4999660.html

posted on   梦琪小生  阅读(513)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
历史上的今天:
2013-12-19 【转】MFC 对话框Border属性设置(None、Thin、Resizing、Dialog Frame)
2013-12-19 MFC 窗体注册 WNDCLASS
2013-12-19 【转】C# 二维码生成
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示