WPF 圆球旋转来实现圆环进度条

15 篇文章 0 订阅

前台:

<!--设置圆的颜色-->
    <UserControl.Resources>
        <SolidColorBrush Color="#f89437" x:Key="CirclesColor"/>
    </UserControl.Resources>

<StackPanel   HorizontalAlignment="Center" VerticalAlignment="Center">
            <Viewbox Width="100" Height="100" HorizontalAlignment="Center" VerticalAlignment="Center">
                <Grid x:Name="LayoutRoot" Background="Transparent" HorizontalAlignment="Center" VerticalAlignment="Center">
                    <!--此处有canvas的加载和卸载事件-->
                    <Canvas RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Center" VerticalAlignment="Center" 
                            Width="120" Height="120" Loaded="HandleLoaded" Unloaded="HandleUnloaded"  >
                        <!--画圆,设置成不同的透明度Opacity-->
                        <Ellipse x:Name="C0" Width="26" Height="26"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="1.0"/>-->
                        <Ellipse x:Name="C1" Width="24" Height="24"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.9"/>-->
                        <Ellipse x:Name="C2" Width="22" Height="22"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.8"/>-->
                        <Ellipse x:Name="C3" Width="20" Height="20"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.7"/>-->
                        <Ellipse x:Name="C4" Width="18" Height="18"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.6"/>-->
                        <Ellipse x:Name="C5" Width="16" Height="16"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.5"/>-->
                        <Ellipse x:Name="C6" Width="14" Height="14"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.4"/>-->
                        <Ellipse x:Name="C7" Width="12" Height="12"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.3"/>-->
                        <Ellipse x:Name="C8" Width="10" Height="10"
                                 Canvas.Left="0" Canvas.Top="0" Stretch="Fill"
                                 Fill="{StaticResource CirclesColor}"/> <!--Opacity="0.2"/>-->
                        <Canvas.RenderTransform>
                            <RotateTransform x:Name="SpinnerRotate" Angle="0" />
                        </Canvas.RenderTransform>
                    </Canvas>
                </Grid>
            </Viewbox>
            <!--这两个针对的元素名称是myUctrl,所以必须要给本界面一个名称-->
            <!--TextBlock里面放置提示信息;Label放置相当于按钮的东西-->
            <TextBlock Text="{Binding TipContent,ElementName=myUctrl}" FontStretch="Medium" HorizontalAlignment="Center"
                       FontSize="14" Margin="0,20,0,0" Foreground="#606266" FontFamily="Microsoft YaHei"/>
            <Label Content="{Binding InnerContent,ElementName=myUctrl}" HorizontalAlignment="Center"/>
        </StackPanel>

后台:


//集成到按指定时间间隔和指定优先级处理的 System.Windows.Threading.Dispatcher 队列中的计时器。
private readonly DispatcherTimer animationTimer;
        
        #region 构造方法
        /// <summary>
        /// 构造方法
        /// </summary>
        public ProgressCircle()
        {
            InitializeComponent();
            animationTimer = new DispatcherTimer(DispatcherPriority.ContextIdle, Dispatcher);
            animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 150); //指定时间间隔
        }
        #endregion

        #region 依赖属性
        #region 得到要显示的提示信息
        /// <summary>
        /// 得到要显示的提示信息
        /// </summary>
        public string TipContent
        {
            get { return (string)GetValue(TipContentProperty); }
            set { SetValue(TipContentProperty, value); }
        }

        public static readonly DependencyProperty TipContentProperty = 
            DependencyProperty.Register("TipContent", typeof(string), typeof(ProgressCircle), new PropertyMetadata("正在处理..."));
        
        #endregion

        #region 按钮的名称--例如:取消
        /// <summary>
        /// 按钮的名称
        /// </summary>
        public object InnerContent
        {
            get { return (object)GetValue(InnerContentProperty); }
            set { SetValue(InnerContentProperty, value); }
        }

        // Using a DependencyProperty as the backing store for InnerContent.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty InnerContentProperty =
            DependencyProperty.Register("InnerContent", typeof(object), typeof(ProgressCircle), new UIPropertyMetadata(null));
        #endregion

        #region 按钮的显示或隐藏
        /// <summary>
        /// 按钮的显示与隐藏
        /// </summary>
        public Visibility InnerContentVisibility
        {
            get { return (Visibility)GetValue(InnerContentVisibilityProperty); }
            set { SetValue(InnerContentVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for InnerContentVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty InnerContentVisibilityProperty =
            DependencyProperty.Register("InnerContentVisibility", typeof(Visibility), typeof(ProgressCircle), new UIPropertyMetadata(Visibility.Collapsed));
        #endregion
        #endregion

        #region 方法
        /// <summary>
        /// 开始方法
        /// </summary>
        private void Start()
        {
            //修改光标的样式,为等待状态
            this.Cursor = Cursors.Wait;
            //超过计时器间隔时发生。
            animationTimer.Tick += HandleAnimationTick;
            animationTimer.Start();
        }

        /// <summary>
        /// 结束方法
        /// </summary>
        private void Stop()
        {
            animationTimer.Stop();
            //修改光标的样式,为箭头
            this.Cursor = Cursors.Arrow;
            animationTimer.Tick -= HandleAnimationTick;
        }

        /// <summary>
        /// 超过计时器间隔时发生。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleAnimationTick(object sender, EventArgs e)
        {
            //设置旋转角度
            SpinnerRotate.Angle = (SpinnerRotate.Angle + 36) % 360;
        }

        /// <summary>
        /// Canvas加载时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleLoaded(object sender, RoutedEventArgs e)
        {
            //圆周长就是:C = π * d 或者C=2*π*r(其中d是圆的直径,r是圆的半径)
            const double offset = Math.PI;  //π
            const double step = Math.PI * 2 / 10.0;

            SetPositin(C0, offset, 0.0, step);
            SetPositin(C1, offset, 1.0, step);
            SetPositin(C2, offset, 2.0, step);
            SetPositin(C3, offset, 3.0, step);
            SetPositin(C4, offset, 4.0, step);
            SetPositin(C5, offset, 5.0, step);
            SetPositin(C6, offset, 6.0, step);
            SetPositin(C7, offset, 7.0, step);
            SetPositin(C8, offset, 8.0, step);
            this.IsVisibleChanged -= HandleVisibleChanged;
            this.IsVisibleChanged += HandleVisibleChanged;
            //DesignerProperties 提供用于与设计器进行通信的附加属性。
            if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
            {
                if (this.Visibility == Visibility.Visible)
                {
                    Start();
                }
            }
        }

        /// <summary>
        /// 确定圆的位置
        /// </summary>
        /// <param name="ellipse"></param>
        /// <param name="offset"></param>
        /// <param name="posOffSet"></param>
        /// <param name="step"></param>
        private void SetPositin(Ellipse ellipse, double offset, double posOffSet, double step)
        {
            ellipse.SetValue(Canvas.LeftProperty, 50.0 + Math.Sin(offset + posOffSet * step) * 50.0);

            ellipse.SetValue(Canvas.TopProperty, 50 + Math.Cos(offset + posOffSet * step) * 50.0);
        }

        /// <summary>
        /// Canvas卸载时
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleUnloaded(object sender, RoutedEventArgs e)
        {
            Stop();
        }

        /// <summary>
        /// 设置显示与隐藏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            bool isVisible = (bool)e.NewValue;

            if (isVisible)
                Start();
            else
                Stop();
        }
        #endregion

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值