zoukankan      html  css  js  c++  java
  • 用WPF实现“等待”小转盘

    我们在开发过程中常常会遇到一些比较耗时的操作,比如一次较慢的网络访问,或者复制一个较大的文件等,如果不使用多线程,而是直接用UI线程去做这些动作,那么就会让用户界面失去响应,带来很不好的用户体验。较好的做法是在界面上呈现出一个小动画,用户看到有东西在动,就不认为程序已经死掉,例如这个:

     当然了,更好的做法是实现一个进度条,但很多时候我们根本不能获取到进度,所以只能显示这么一个小转盘,小转盘效果的比较简单的实现方法是显示一个小小的gif,但WPF默认的Image控件并不直接支持gif动画效果,所幸的是我们可以通过一个叫“WpfAnimatedGif”第三方的库来很方便地把这个动画效果显示出来,这个库可以通过NuGet获取到,我提供的完整代码下载里也有。这是我的Demo的效果图:

    小转盘出现的同时,我们希望能够暂时阻挡用户的操作,我最早想到的办法是把窗口Disable掉,也就是把它的IsEnabled属性设为False,但这样做可能达不到我们想要的效果,因为这样只能把窗口的客户区Disabled掉,而非客户区却仍然可以操作,比如标题栏上的最小化,最大化和关闭按钮,所以比较好的做法是用一个模态对话框。这是我设计的模态对话框:

    <Window x:Class="WaitingDemo.WaitingDlg"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:gif="http://wpfanimatedgif.codeplex.com"
            Title="WaitingDlg" Height="100" Width="400" WindowStyle="None" Background="Transparent" AllowsTransparency="True"
            WindowStartupLocation="CenterOwner" Closing="Window_Closing" Loaded="Window_Loaded"
            TextOptions.TextFormattingMode="Display">
        <Grid>
            <Border CornerRadius="5" Height="40" BorderBrush="Black" BorderThickness="1" Background="White" Width="350">
                <Border.Effect>
                    <DropShadowEffect Color="Black"></DropShadowEffect>
                </Border.Effect>
                <Grid VerticalAlignment="Center">
                    <Image gif:ImageBehavior.AnimatedSource="loading.gif" Width="28" Height="28" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="5,0,0,0"/>
                    <TextBlock Name="tbPrompt" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.ColumnSpan="2" Margin="0,7">任务执行中...</TextBlock>
                </Grid>
            </Border>
        </Grid>
    </Window>

    这是几个要注意的属性设置:

    • WindowStyle - 设置为None来使得这个模态对话框没有标题栏,当然也就没有了最小化、最大化和关闭按钮
    • Background - 设置为Transparent来让这个模态对话框背景透明
    • AllowsTransparency - 如果不把这个属性设置为True,那模态对话框的依然是不透明的,你将看到一个黑框
    • WindowStartupLocation - 设置为CenterOwner让模态对话框默认居中显示

    细心的你也许还发觉了:只是不显示关闭按钮还是不够的,用户还是可以通过<Alt>+<F4>来关闭这个对话框,所以需要处理Closing事件,判断这个关闭动作是否我们的程序提出来的。

    对于处理任务,我创建了一个接口:

        public interface ILongTimeTask
        {
            void Start(WaitingDlg dlg);
        }

    将WaitingDlg传入的原因是想让工作线程结束的时候关闭掉这个模态对话框:

            public void TaskEnd(Object result)
            {
                m_taskResult = result; //用于返回执行的结果(也可以为null)
                m_bCloseByMe = true; //这个标志表示“关闭”动作由我们的程序提出
                Dispatcher.BeginInvoke(new CloseMethod(Close)); //工作线程对界面元素的操作必须用这种调用方式
            }

    完整代码:下载

  • 相关阅读:
    详解 注解
    线段树分治
    实用Trick
    CF932F(李超线段树+dp)
    CF24D Broken robot(高斯消元)
    LCT学习笔记
    [HNOI2008]GT考试
    [AHOI2009]中国象棋
    [APIO2012]派遣
    CF961G Partitions
  • 原文地址:https://www.cnblogs.com/guogangj/p/2938971.html
Copyright © 2011-2022 走看看