zoukankan      html  css  js  c++  java
  • 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 = 0;
            #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(0, 0, 0, 0, TimeSpan);
                if (EllipseCount < 1)
                {
                    EllipseCount = 12;
                }
                for (int i = 0; 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(100, 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 * 2) / count;
    
                //根据圆中正弦、余弦计算距离
                int index = 0;
                foreach (var element in children)
                {
                    var ellipse = element as Ellipse;
                    //透明度
                    var opacity = Convert.ToDouble(index)/(count - 1);
                    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) % 360;
            }
            #endregion
        }
    View Code

    数据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"/>
  • 相关阅读:
    2019-4-16-C#-使用反射获取私有属性的方法
    2019-5-21-C#-命令行如何静默调用-del-删除文件
    2019-6-14-WPF-shows-that-some-windows-in-multithreading-will-be-locked-in-the-PenThreadWorker-constr...
    2019-9-11-完整的-P2P-应用需要包含哪些功能
    2019-3-1-VisualStudio-扩展开发-获得输出窗口内容
    2018-10-19-C#-序列类为-xml-可以使用的特性大全
    2018-8-10-win10-uwp-手把手教你使用-asp-dotnet-core-做-cs-程序
    2018-10-31-win10-uwp-使用-asp-dotnet-core-做图床服务器客户端
    2018-8-10-docfx-做一个和微软一样的文档平台
    linux分区方案
  • 原文地址:https://www.cnblogs.com/kybs0/p/5765684.html
Copyright © 2011-2022 走看看