百度了一下,粗略看了几个国内野人的做法,花了时间看下去感觉不太好用(比如有Loading居然只是作为窗体的一个局部控件的,没法全屏遮罩,那要你有何用?),于是谷歌找轮子去。

好用的轮子:http://wpftoolkit.codeplex.com/wikipage?title=BusyIndicator

引入DLL(在官网或者Nuget里下载)、引入名称空间等步骤根据官方的文档来操作就好了,很简单。

测试如下:
前台代码 MainWindow.xaml:

<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"> <!-- 如有需要,可以引入样式资源 -->
<!--<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Style/LoadingMaskStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>--> <StackPanel VerticalAlignment="Center"> <xctk:BusyIndicator x:Name="_busyIndicator" IsBusy="False"
BusyContent="少女祈祷中..." Background="Red">
<!--<xctk:BusyIndicator.OverlayStyle>
<Style TargetType="Rectangle">
<Setter Property="Fill" Value="#ffffeeee"/>
</Style>
</xctk:BusyIndicator.OverlayStyle>-->
<!--<xctk:BusyIndicator.ProgressBarStyle>
<Style TargetType="ProgressBar">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</xctk:BusyIndicator.ProgressBarStyle>--> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Click="Show" Content="LLLL" Height="40" Width="60"/>
<Button Click="Show" Content="LLLL" Height="40" Width="60"/>
<Button x:Name="btn" Click="btn_OnClick" Content="测试" Height="40" Width="60"/>
<Button Click="Show" Content="RRRR" Height="40" Width="60"/>
<Button Click="Show" Content="RRRR" Height="40" Width="60"/>
</StackPanel>
</xctk:BusyIndicator>
</StackPanel>
</Window>

对应的后台代码 MainWindow.xaml.cs:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} private void btn_OnClick(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
//this is where the long running process should go
worker.DoWork += (o, ea) =>
{
//no direct interaction with the UI is allowed from this method
for (int i = 0; i < 100; i++)
{
System.Threading.Thread.Sleep(100);
}
};
worker.RunWorkerCompleted += (o, ea) =>
{
//work has completed. you can now interact with the UI
_busyIndicator.IsBusy = false;
};
//set the IsBusy before you start the thread
_busyIndicator.IsBusy = true;
worker.RunWorkerAsync();
} private void Show(object sender, RoutedEventArgs e)
{
MessageBox.Show("还能点!");
}
}
}

运行效果如下:

注意点:

  • 想要这个BusyIndicator全屏遮罩,需要把它作为这个Window的直接子节点。而这个BusyIndicator控件自身也只能包含一个子节点,所以可用一个Grid或StackPanel标签做包裹。
  • 官方文档中没有说到BusyIndicator的XMAL全屏遮罩写法,我是看youtube这个小哥这么写的:

https://www.youtube.com/watch?v=1h_mLA-eE40


2016.12.29下午更新:

发现一个问题,当在worker.DoWork委托中执行的操作需要修改UI时,会发生运行时异常:

Additional information: 该类型的 CollectionView 不支持从调度程序线程以外的线程对其 SourceCollection 进行的更改。

谷歌一下:
http://stackoverflow.com/questions/18331723/this-type-of-collectionview-does-not-support-changes-to-its-sourcecollection-fro

意思是说,UI是由UI线程创建并维护的,BackgroundWorker对象作为一个新建的子线程,无法跨线程操作UI(这点跟Android很像嘛),想要跨线程操作UI,需要使用Dispatcher分发器机制。所以worker.DoWork的代码修改一下就好了:

worker.DoWork += (o, ea) =>
{
//no direct interaction with the UI is allowed from this method
// 不需要操作UI的代码
// ... // 需要操作UI的代码
App.Current.Dispatcher.Invoke((Action)delegate
{
// 如MVVM中其他Controller、ViewModel中操作UI的方法
designController.Initialize();
webImageViewModel.UpdateImages(designId);
});
};

重要参考:

https://elegantcode.com/2009/07/03/wpf-multithreading-using-the-backgroundworker-and-reporting-the-progress-to-the-ui/
https://elegantcode.com/2011/10/07/extended-wpf-toolkitusing-the-busyindicator/ 最后一个例子有提及Dispatcher
https://vkishorekumar.wordpress.com/2011/07/18/what-is-thread-affinity/ 报错原因:线程的紧密性(亲和性?)

【WPF】BusyIndicator做Loading遮罩层的更多相关文章

  1. WPF loading遮罩层 LoadingMask

    原文:WPF loading遮罩层 LoadingMask 大家可能很纠结在异步query数据的时候想在wpf程序中显示一个loading的遮罩吧 今天就为大家介绍下遮罩的制作 源码下载 点击此处 先 ...

  2. js实现的简单遮罩层

    超级简单的一个实现,可能会有局限性,贵在简单易懂,使用的时候执行前loading,执行成功后loaded /* * 显示loading遮罩层 */ function loading() { var m ...

  3. JS实现遮罩层

    /* * 显示loading遮罩层 */ function loading() { var mask_bg = document.createElement("div"); mas ...

  4. js 遮罩层 loading 效果

    //调用方法 //关闭事件<button onclick='LayerHide()'>关闭</button>,在loadDiv(text)中,剔除出来 //调用LayerSho ...

  5. C# Winform 实现自定义半透明loading加载遮罩层

    在网页中通过div+css实现半透明效果不难,今天我们看看一种在winfrom中实现的方法: 效果图如下,正常时: 显示遮罩层时: 自定义遮罩层控件的源码如下: View Row Code 1 usi ...

  6. Android UI设计--半透明效果对话框及activity(可做遮罩层)

    下面是style的一些属性及其解释 <style name="dialog_translucent" parent="@android:style/Theme.Di ...

  7. Android自定义遮罩层设计

    在做网页设计时,前端设计人员会经常用到基于JS开发的遮罩层,并且背景半透明.这样的效果怎么样在Android上实现呢?这个实现并不困难,先来上效果图: <ignore_js_op> 201 ...

  8. html+css源码之实现登录弹出框遮罩层效果

    在web开发中,很多网站都做了一些特别炫丽的效果,比如用户登录弹框遮罩层效果,本文章向大家介绍css如何实现登录弹出框遮罩层效果,需要的朋友可以参考一下本文章的源代码. html+css实现登录弹出框 ...

  9. div+css遮罩层

    曾被问到这个问题,不知所措,后来在网上找到了.大神文章:http://www.cnblogs.com/aspx-net/archive/2011/03/11/1981071.html 我想实现的效果没 ...

随机推荐

  1. MYSQL查询一周内的数据(最近7天的)

    select * from wap_content where week(created_at) = week(now) 如果你要严格要求是某一年的,那可以这样 查询一天: select * from ...

  2. 架构-LAMP特级学习(网站大存储量解决方案)

    数据库采用主从.分区技术 数据库优化

  3. JDK 生成数字证书

    JDK(keytool.exe)生成数字证书 2010-11-21 15:52 QUOTE: keytool JAVA是个密钥和证书管理工具.它使用户能够管理自己的公钥/私钥对及相关证书,用于(通过数 ...

  4. Mint17 一些安装备忘

    1,中文输入法: sudo apt-add-repository ppa:fcitx-team/dailybuild-fcitx-master sudo apt-get update sudo apt ...

  5. java.lang.NoClassDefFoundError: Could not initialize class com.demo.jdbc.utils.MyJdbcUtils

    jdbc编写工具类的过程中测试失败, 出现如下错误:   原因:初始化的过程中执行静态代码块的过程中出现错误, 也就是说, 加载配置文件错误: 没有加载到指定路径的配置文件. 我的MyJdbcUtil ...

  6. CYDIA装了个插件,想删除怎么都删除,电脑如何删除插件?

    http://bbs.weiphone.com/read-htm-tid-3670917.html 装了个插件,想删除怎么都删除不掉不要跟我说在CYDIA里面删除.,在CYDIA里点击该插件就会闪退C ...

  7. Ubuntu Pycharm不能同时选中多行解决方法

    转自http://blog.csdn.net/yaoqi_isee/article/details/77866309 问题描述 Pycharm和Sublime有一个很好用的特性就是可以同时选中多行进行 ...

  8. Unix环境高级编程(八)进程关系

    本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用.通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态.先将本章基本的知识点总结如下,日后再看时候 ...

  9. 使用Apktools反编译apk应用

    使用Apktools反编译apk应用 1.获取APK的classes.dex文件: 得到你想要的应用的apk文件,用解压软件打开apk,从apk中复制出classes.dex文件. 2.classes ...

  10. Xfire实现webservice各种报错详解

    一.No write method for property {http://vo.aa.com}new in class com.aa.vo.TA 使用xfire的ws调用时,会将对象与xml进行捆 ...