【Win 10 应用开发】通过数据绑定更新进度条
实现 INotifyPropertyChanged 接口可以在属性更改后通知数据的使用者,这个相信大伙儿都知道。于是,有朋友会问:对于要实时显示进度的情况,比如更新进度条,能用这个实现吗?
当然是可以的,也很简单,定义一个类,实现 INotifyPropertyChanged 接口,然后公开表示处理进度的属性,并且在属性更改后引发通知事件。
然后把该类的实例与进度条进行绑定即可,和一般的绑定差不多。不过,有一点需要强调:通常是把属性更改通知发送给UI对象的,多数情况下,我们在处理一些耗时操作都会在另一个线程上执行,这就使得在实现这个接口时,引发PropertyChanged 事件的时候容易发生错误。为了避免错误发生,在实现接口时,应当用Dispatcher来引发事件,确保能在UI线程上执行。
一个比较不错的方法,是先弄个抽象类,让它实现 INotifyPropertyChanged 接口,后面你所定义的各种 Model 类就可以从这个抽象类派生,这样会相当省事。
比如这样:
public abstract class NotifyPropertyChangedBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged; protected async void OnPropertyChanged([CallerMemberName] string propName = "")
{
await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.High,
() =>
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));
});
}
}
因为在引发属性更改通知时需要指定属性名称,咱们使用一个技巧,在 OnPropertyChanged 方法的参数上加一个 CallerMemberNameAttribute,这么一来,只要在被更改的属性的set方法中调用这个方法,就会自动把属性的名字传给参数了,也不用我们手动输,既免去繁杂工作,也不容易弄错。注意参数在附加CallerMemberNameAttribute后一定要给它一个默认值,说白了就是让这个参数变成可选参数,以方便运行时库在运行阶段修改它。
调用 Window.Current.Dispatcher.RunAsync 方法确保事件引发的代码是在UI线程上执行的,就不会出现因交叉线程更改用户界面而导致的异常。
好,上面说了一车的废话,下面我们来定义一个表示进度数据的类,主要包括进度的最大值、最小值,以及当前进度,这个类从刚才定义的 NotifyPropertyChangedBase 类派生。
public sealed class ProgressData : NotifyPropertyChangedBase
{
private int _max, _min, _currvalue; public int Max
{
get { return _max; }
set
{
if (value != _max)
{
_max = value;
OnPropertyChanged();
}
}
} public int Min
{
get { return _min; }
set
{
if (value != _min)
{
_min = value;
OnPropertyChanged();
}
}
} public int CurrentValue
{
get { return _currvalue; }
set
{
if (value != _currvalue)
{
_currvalue = value;
OnPropertyChanged();
}
}
}
}
在用户界面上声明 ProgressBar 控件,然后绑定到上面类型的属性。
<ProgressBar Name="pb" Height="25" Margin="3,30,5,2"
Maximum="{Binding Max}"
Minimum="{Binding Min}"
Value="{Binding CurrentValue}"
SmallChange="1.0"/>
如何让 ProgressData 实例与 ProgressBar 控件关联呢,这好办,因为有一个 DataContext 属性,它可以赋任何类型的值,然后控件中的绑定会从该属性的值中寻找数据。
下面我们来关联一下。
m_progressdata = new ProgressData();
m_progressdata.Max = ;
m_progressdata.Min = ;
m_progressdata.CurrentValue = ;
this.pb.DataContext = m_progressdata;
注意看最后一行,不解释。
然后定义一个基于 Task 的异步方法,来模拟在新线程上处理数据。
async Task TestSomethingAsync()
{
while (m_progressdata.CurrentValue < m_progressdata.Max)
{
m_progressdata.CurrentValue++;
await Task.Delay();
}
}
随后可以进行测试了。
private async void OnClick(object sender, RoutedEventArgs e)
{
m_progressdata.CurrentValue = m_progressdata.Min;
Button btn = sender as Button;
btn.IsEnabled = false;
await TestSomethingAsync();
btn.IsEnabled = true;
}
至此,就完成进度的绑定了,当你在线程中处理进度时,你可以不用管UI上用什么来显示进度了,哪怕是用文本显示,或用进度条来显示,都无所谓,数据与界面分离。
看看效果,还是挺不错的。

这种方法除了在UWP中可用,同样适用于WPF项目,因为都是一脉相承的,所以老周一直坚持:只要WPF学好了,别的都好办。
【Win 10 应用开发】通过数据绑定更新进度条的更多相关文章
- android AsyncTask异步下载并更新进度条
AsyncTask异步下载并更新进度条 //如果不是很明白请看上篇文章的异步下载 AsyncTask<String, Integer, String> 第一个参数:String 传入 ...
- WPF BackGroundWord 异步加载更新进度条示例
<Window x:Class="AsynchronousLoading.MainWindow" xmlns="http://schemas.microsoft.c ...
- [wxWidgets]_[0基础]_[经常更新进度条程序]
场景: 1. 非常根据程序的进展需要处理业务,以更新进度条,进度条的目的是为了让用户知道业务流程的进度.一个进度条程序更友好,让用户知道在程序执行.不是没有反应. 2. 现在更新见过这两种方法的进展. ...
- Handler实现线程之间的通信-下载文件动态更新进度条
1. 原理 每一个线程对应一个消息队列MessageQueue,实现线程之间的通信,可通过Handler对象将数据装进Message中,再将消息加入消息队列,而后线程会依次处理消息队列中的消息. 2. ...
- AsyncTask用法解析-下载文件动态更新进度条
1. 泛型 AysncTask<Params, Progress, Result> Params:启动任务时传入的参数,通过调用asyncTask.execute(param)方法传入. ...
- Xamarin XAML语言教程使用Progress属性数据绑定设置进度条进度
Xamarin XAML语言教程使用Progress属性数据绑定设置进度条进度 开发者除了可以为ProgressBar定义的Progress属性直接赋双精度类型的值外,还可以通过数据绑定的方式为该属性 ...
- 【Win 10 应用开发】导入.pfx证书
这个功能其实并不常用,一般开发较少涉及到证书,不过,简单了解一下还是有必要的. 先来说说制作测试证书的方法,这里老周讲两种方法,可以生成用于测试的.pfx文件. 产生证书,大家都知道有个makecer ...
- 【Win 10应用开发】Adaptive磁贴模板的XML文档结构
在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴的新XML模板. 同样道理,你依旧可以使用8.1时候的磁贴模板,在win ...
- 【Win 10 应用开发】RTM版的UAP项目解剖
Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...
随机推荐
- ABP入门系列(2)——通过模板创建MAP版本项目
一.从官网创建模板项目 进入官网下载模板项目 依次按下图选择: 输入验证码开始下载 下载提示: 二.启动项目 使用VS2015打开项目,还原Nuget包: 设置以Web结尾的项目,设置为启动项目: 打 ...
- 基于DDD的现代ASP.NET开发框架--ABP系列文章总目录
ABP相关岗位招聘:给热爱.NET新技术和ABP框架的朋友带来一个高薪的工作机会 ABP交流会录像视频:ABP架构设计交流群-7月18日上海线下交流会的内容分享(有高清录像视频的链接) 代码自动生成: ...
- JavaScript中Math对象的方法介绍
1.比较最值方法 比较最值有两种方法,max() 和 min() 方法. 1.1 max() 方法,比较一组数值中的最大值,返回最大值. var maxnum = Math.max(12,6,43,5 ...
- 多线程的通信和同步(Java并发编程的艺术--笔记)
1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递. 2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...
- 使用 JavaScript 和 canvas 做精确的像素碰撞检测
原文地址:Pixel accurate collision detection with Javascript and Canvas 译者:nzbin 我正在开发一个需要再次使用碰撞检测的游戏.我通常 ...
- 关于python的bottle框架跨域请求报错问题的处理
在用python的bottle框架开发时,前端使用ajax跨域访问时,js代码老是进入不了success,而是进入了error,而返回的状态却是200.url直接在浏览器访问也是正常的,浏览器按F12 ...
- javascript 判断参数类型大全
js 判断类型的在开发中是很常用的,因为js 是弱类型的语言,var 可以接受任何形式的类型,但是在真正的开发中,我们需要根据不同类型做不同的处理,所以这个是必须的精通. 首先需要知道 typeof这 ...
- Windows下Visual studio 2013 编译 Audacity
编译的Audacity版本为2.1.2,由于实在windows下编译,其源代码可以从Github上取得 git clone https://github.com/audacity/audacity. ...
- JavaScript基础知识总结(四)
JavaScript语法 八.函数 函数就是完成某个功能的一组语句,函数由关键字function + 函数名 + 加一组参数定义: 函数在定义后可以被重复调用,通常将常用的功能写成一个函数,利用函数可 ...
- DOM的小练习,两个表格之间数据的移动
本次讲的是两个表格之间数据的移动,左边的表格移动到右边,并且左边表格移动内容消失. <head> <meta http-equiv="Content-Type" ...