WPF加载等待动画

简介: 原文:WPF加载等待动画 原文地址:https://www.codeproject.com/Articles/57984/WPF-Loading-Wait-Adorner 界面遮罩 等待动画全局颜色 ...
原文: WPF加载等待动画

原文地址:https://www.codeproject.com/Articles/57984/WPF-Loading-Wait-Adorner

img_dddefb69135aea844b7e28a97101e851.gif
界面遮罩

    <UserControl.Background>
        <SolidColorBrush Color="Black" Opacity=".20" />
    </UserControl.Background>

等待动画全局颜色

 <UserControl.Resources>
        <SolidColorBrush Color="CornflowerBlue" x:Key="CirclesColor" />
    </UserControl.Resources>

等待动画中的小圆

 <Ellipse x:Name="C0" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="1.0"/>
<UserControl x:Class="ControlSamples.LoadingWait"
             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" 
             xmlns:local="clr-namespace:ControlSamples"
             IsVisibleChanged="HandleVisibleChanged"
             mc:Ignorable="d" >
    <UserControl.Background>
        <SolidColorBrush Color="Black" Opacity=".20" />
    </UserControl.Background>
    <UserControl.Resources>
        <SolidColorBrush Color="CornflowerBlue" x:Key="CirclesColor" />
    </UserControl.Resources>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
        <Viewbox Width="100" Height="100"
            HorizontalAlignment="Center"
            VerticalAlignment="Center">
            <Grid x:Name="LayoutRoot" 
                Background="Transparent"
                ToolTip="..."
                HorizontalAlignment="Center"
                VerticalAlignment="Center">
                <Canvas RenderTransformOrigin="0.5,0.5"
                    HorizontalAlignment="Center"
                    VerticalAlignment="Center" Width="120"
                    Height="120" Loaded="HandleLoaded"
                    Unloaded="HandleUnloaded"  >
                    <Ellipse x:Name="C0" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="1.0"/>
                    <Ellipse x:Name="C1" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="0.9"/>
                    <Ellipse x:Name="C2" Width="20" Height="20"
                         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="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="0.6"/>
                    <Ellipse x:Name="C5" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="0.5"/>
                    <Ellipse x:Name="C6" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="0.4"/>
                    <Ellipse x:Name="C7" Width="20" Height="20"
                         Canvas.Left="0"
                         Canvas.Top="0" Stretch="Fill"
                         Fill="{StaticResource CirclesColor}" Opacity="0.3"/>
                    <Ellipse x:Name="C8" Width="20" Height="20"
                         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>
        <TextBlock x:Name="TextControl" FontSize="24" Text="" HorizontalAlignment="Center" VerticalAlignment="Center" TextWrapping="Wrap" Margin="20"></TextBlock>
    </StackPanel>
</UserControl>

后台业务代码,添加了几项属性、动画控制、小圆的位置设置

    /// <summary>
    /// LoadingWait.xaml 的交互逻辑
    /// </summary>
    public partial class LoadingWait : UserControl
    {
        #region Data
        private readonly DispatcherTimer animationTimer;

        public int TextSize
        {
            get { return (int)GetValue(TextSizeProperty); }
            set { SetValue(TextSizeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TextSize.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextSizeProperty =
            DependencyProperty.Register("TextSize", typeof(int), typeof(LoadingWait), new PropertyMetadata(
                defaultValue: 24,
                propertyChangedCallback: new PropertyChangedCallback(
                    (sender, e) => {
                        var loading = sender as LoadingWait;
                        if(loading != null) {
                            loading.TextControl.FontSize = (int)e.NewValue;
                        }
                    })
                ));


        public Color TextColor
        {
            get { return (Color)GetValue(TextColorProperty); }
            set { SetValue(TextColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for TextColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextColorProperty =
            DependencyProperty.Register("TextColor", typeof(Color), typeof(LoadingWait), new PropertyMetadata(
                defaultValue: Colors.Black,
                propertyChangedCallback: new PropertyChangedCallback(
                    (sender, e) => {
                        var loading = sender as LoadingWait;
                        if(loading != null) {
                            loading.TextControl.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString(e.NewValue.ToString()));
                        }
                    }),
                coerceValueCallback: new CoerceValueCallback((sender, e) => {
                    LoadingWait loading = (LoadingWait)sender;
                    try {
                        return (Color)ColorConverter.ConvertFromString(e.ToString());
                    }
                    catch(Exception ex) {
                        return Colors.Black;
                    }
                })
                ));



        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(LoadingWait), new PropertyMetadata(
                defaultValue: string.Empty,
                propertyChangedCallback: new PropertyChangedCallback(
                    (sender, e) => {
                        var loading = sender as LoadingWait;
                        if(loading != null) {
                            loading.TextControl.Text = e.NewValue.ToString();
                        }
                    })
                ));


        public string Tip
        {
            get { return (string)GetValue(TipProperty); }
            set { SetValue(TipProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Tip.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TipProperty =
            DependencyProperty.Register("Tip", typeof(string), typeof(LoadingWait), new PropertyMetadata(
                defaultValue: string.Empty,
                propertyChangedCallback: new PropertyChangedCallback(
                    (sender, e) => {
                        var loading = sender as LoadingWait;
                        if(loading != null) {
                            loading.LayoutRoot.ToolTip = e.NewValue;
                        }
                    })
                ));

        #endregion

        #region Constructor
        public LoadingWait() {
            InitializeComponent();

            animationTimer = new DispatcherTimer(
                DispatcherPriority.ContextIdle, Dispatcher);
            animationTimer.Interval = new TimeSpan(0, 0, 0, 0, 75);
        }
        #endregion

        #region Private Methods
        private void Start() {
            Mouse.OverrideCursor = Cursors.Wait;
            animationTimer.Tick += HandleAnimationTick;
            animationTimer.Start();
        }

        private void Stop() {
            animationTimer.Stop();
            Mouse.OverrideCursor = Cursors.Arrow;
            animationTimer.Tick -= HandleAnimationTick;
        }

        private void HandleAnimationTick(object sender, EventArgs e) {
            SpinnerRotate.Angle = (SpinnerRotate.Angle + 36) % 360;
        }

        private void HandleLoaded(object sender, RoutedEventArgs e) {
            const double offset = Math.PI;
            const double step = Math.PI * 2 / 10.0;

            SetPosition(C0, offset, 0.0, step);
            SetPosition(C1, offset, 1.0, step);
            SetPosition(C2, offset, 2.0, step);
            SetPosition(C3, offset, 3.0, step);
            SetPosition(C4, offset, 4.0, step);
            SetPosition(C5, offset, 5.0, step);
            SetPosition(C6, offset, 6.0, step);
            SetPosition(C7, offset, 7.0, step);
            SetPosition(C8, offset, 8.0, step);
        }

        //设置动画中小圆的位置
        private void SetPosition(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);
        }

        private void HandleUnloaded(object sender, RoutedEventArgs e) {
            Stop();
        }

        //显示控件就启动动画,隐藏(不显示)就停止动画
        private void HandleVisibleChanged(object sender,
            DependencyPropertyChangedEventArgs e) {
            bool isVisible = (bool)e.NewValue;

            if(isVisible)
                Start();
            else
                Stop();
        }
        #endregion
    }
目录
相关文章
|
3月前
|
C#
WPF中动画教程(DoubleAnimation的基本使用)
WPF中动画教程(DoubleAnimation的基本使用)
69 0
|
2月前
|
算法 C# Windows
不可不知的WPF动画(Animation)
【9月更文挑战第19天】在 WPF(Windows Presentation Foundation)中,动画能为应用程序增添生动性和交互性。主要类型包括线性动画和关键帧动画,可针对依赖属性和自定义属性操作。触发方式有事件触发和自动触发,支持暂停、恢复及停止控制。合理使用这些功能并注意性能优化,可创建引人入胜的用户界面。
|
3月前
|
C# UED 开发者
WPF与性能优化:掌握这些核心技巧,让你的应用从卡顿到丝滑,彻底告别延迟,实现响应速度质的飞跃——从布局到动画全面剖析与实例演示
【8月更文挑战第31天】本文通过对比优化前后的方法,详细探讨了提升WPF应用响应速度的策略。文章首先分析了常见的性能瓶颈,如复杂的XAML布局、耗时的事件处理、不当的数据绑定及繁重的动画效果。接着,通过具体示例展示了如何简化XAML结构、使用后台线程处理事件、调整数据绑定设置以及利用DirectX优化动画,从而有效提升应用性能。通过这些优化措施,WPF应用将更加流畅,用户体验也将得到显著改善。
220 1
|
3月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
171 0
|
3月前
|
存储 C# 数据格式
WPF动画教程(PointAnimationUsingPath的使用)
WPF动画教程(PointAnimationUsingPath的使用)
48 0
|
6月前
|
C#
WPF —— 动画缩放变换
`ScaleTransform`用于二维x-y坐标系中对象的缩放,可沿X或Y轴调整。在故事板中,通过RenderTransform.ScaleX和ScaleY属性控制缩放。示例代码展示了如何设置按钮的RenderTransformOrigin、Background等属性,并通过LayoutTransform应用ScaleTransform。当鼠标进入按钮时,EventTrigger启动DoubleAnimation实现X和Y轴的缩放动画。最后,展示了如何将动画集成到自定义按钮样式中。
173 0
|
C#
WPF技术之动画系列-上下运动
本例子展现动画小球上下循环运动
220 0
WPF从外部文件或者程序集加载样式或其他静态资源
WPF从外部文件或者程序集加载样式或其他静态资源
WPF从外部文件或者程序集加载样式或其他静态资源
|
C#
关于WPF的ComboBox中Items太多而导致加载过慢的问题
原文:关于WPF的ComboBox中Items太多而导致加载过慢的问题                                     【WFP疑难】关于WPF的ComboBox中Items太多而导致加载过慢的问题                                      ...
1359 0
|
C#
WPF编游戏系列 之六 动画效果(1)
原文:WPF编游戏系列 之六 动画效果(1)        本篇主要针对界面进行动画效果处理。首先在打开或关闭界面时,使其产生动态效果而不是生硬的显示或消失(如下图)。其次在鼠标放到关闭窗口图标上时,使其出现闪动效果。
696 0