(MVVM) ListBox Binding 和 实时刷新
当需要用Lisbbox 来log 一些记录的时候,ObservableCollection 并不可以是记录实时的反应在WPF 的UI上面。
这个时候就需要用一个异步collection 来完成。
/// <summary>
/// Represents the asynchronous observable collection.
/// </summary>
/// <typeparam name="T"></typeparam>
public class AsyncObservableCollection<T> : ObservableCollection<T>
{
/// <summary>
/// The _synchronization context
/// </summary>
private readonly SynchronizationContext synchronizationContext = SynchronizationContext.Current; /// <summary>
/// Initializes a new instance of the <see cref="AsyncObservableCollection{T}"/> class.
/// </summary>
public AsyncObservableCollection()
{
} /// <summary>
/// Initializes a new instance of the <see cref="AsyncObservableCollection{T}"/> class.
/// </summary>
/// <param name="list">The list.</param>
public AsyncObservableCollection(IEnumerable<T> list)
: base(list)
{
} /// <summary>
/// Inserts the item.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
protected override void InsertItem(int index, T item)
{
this.ExecuteOnSyncContext(() => base.InsertItem(index, item));
} /// <summary>
/// Removes the item.
/// </summary>
/// <param name="index">The index.</param>
protected override void RemoveItem(int index)
{
this.ExecuteOnSyncContext(() => base.RemoveItem(index));
} /// <summary>
/// Sets the item.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
protected override void SetItem(int index, T item)
{
this.ExecuteOnSyncContext(() => base.SetItem(index, item));
} /// <summary>
/// Moves the item.
/// </summary>
/// <param name="oldIndex">The old index.</param>
/// <param name="newIndex">The new index.</param>
protected override void MoveItem(int oldIndex, int newIndex)
{
this.ExecuteOnSyncContext(() => base.MoveItem(oldIndex, newIndex));
} /// <summary>
/// Clears the items.
/// </summary>
protected override void ClearItems()
{
this.ExecuteOnSyncContext(() => base.ClearItems());
} /// <summary>
/// Executes the on synchronize context.
/// </summary>
/// <param name="action">The action.</param>
private void ExecuteOnSyncContext(Action action)
{
if (SynchronizationContext.Current == this.synchronizationContext)
{
action();
}
else
{
this.synchronizationContext.Send(_ => action(), null);
}
}
}
另外还需要启用一个新的线程来更新collection
后续补充:
UI 编程中只要搞清楚如下两点:
1. UI 线程(主线程,入Dispatcher队,只用于更新UI), 在UI线程里面不要做耗时的操作,所有UI线程里面都是用于更新UI的。
2. 所有的耗时操作全部放到另外的线程里去做。
搞清楚如上两点,这个Listbox的更新可以通过如下代码来实现了。
// Start a non-UI thread to do some works without blocking UI thread.
Task.Factory.StartNew(() =>
{
for (int i = ; i < ; i++)
{
// Put UI change enter dispatcher queue.
this.Dispatcher.Invoke(() =>
{
((LoggerListBoxViewModel)(this.DataContext)).Logger.Add("Log~~~~.." + i);
}); // Other works.
Thread.Sleep();
}
});
在ViewModel裏面可以如下更新:
private void LogMessage(string message)
{
// Start a non-UI thread to do some works without blocking UI thread.
Task.Factory.StartNew(() =>
{
// Put UI change enter dispatcher queue.
Application.Current.Dispatcher.Invoke(() =>
{
this.Logger.Add(message);
});
});
}
注意,如上,Disparter.Invoke是UI线程,里面不能做耗时的工作。仅仅用于更新 UI。
(MVVM) ListBox Binding 和 实时刷新的更多相关文章
- 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令
[源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd ...
- 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令
[源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd ...
- 使用SignalR实现比特币价格实时刷新
ASP.NET SignalR是微软支持的一个运行在 Dot NET 平台上的 HTML Websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重 ...
- Sublime Text 3配置LiveReload实现实时刷新
今天看到一款很强大的插件,LiveReload,实时刷新,也就是说写完html/css/js等不用再到浏览器里按F5啦,在Ctrl+S时浏览器会自动刷新,是不是想想都很爽... Chrome:(据说支 ...
- Gulp-livereload:实时刷新编码
实现功能 监听指定目录下的所有文件,实时动态刷新页面 安装(Install) 功能的实现是借助 gulp-connect 插件完成的;所以,首先通过下面命令完成插件安装: npm install -- ...
- tab栏切换,内容为不断实时刷新数据的vue实现方法
先说一下产品需求,就是有几个tab栏,每个tab栏对应的ajax请求不一样,内容区域一样,内容为实时刷新数据,每3s需要重新请求,返回的数据在内容区域展示,每点击一次tab栏需停止其他tab栏ajax ...
- webpack-dev-server 搭建本地服务以及浏览器实时刷新
一.概述开发项目中为了保证上线,开发项目是都需要使用localhost进行开发,以前的做法就是本地搭建Apache或者Tomcat服务器.有的前端开发人员 对服务器的搭建和配置并不熟悉,这个时候需要后 ...
- JAVAFX之tableview界面实时刷新导致的内存溢出(自己挖的坑,爬着也要出来啊0.0)
这几天遇到了一个问题,不幸开发的一个cs架构的工具,客户端开启后,内存一直在缓慢增长最终导致进程卡死,花了4天时间,终于爬出来了... 客户端通过timer定时器每30秒查询一次数据库以及一些业务逻辑 ...
- js获取当前时间并实时刷新
效果如图: 代码如下: <html> <head> <title>js获取当前时间并实时刷新</title> <script> //页面加载 ...
随机推荐
- wifi测距
#include "ESP8266WiFi.h" #include "math.h" //d = 10^(A-(abs(rssi)) / (10 * n)) 信 ...
- 主流服务器虚拟化技术简单使用——Hyper-V(二)
当在多台Windows Server上部署了hyper-v的时候,需要采用合适的方法管理这些hyper-v节点. 远程桌面 最简单的方法就是逐台远程桌面登陆Windows Server,再使用每台本地 ...
- spring测试save方法报错
用test类测试service的save方法时,报错如下: 2018-08-24 21:52:13,506 - could not read a hi value com.mysql.jdbc.exc ...
- python __getattribute__、__getattr__、__setattr__详解
__getattribute__ 官方文档中描述如下: 该方法可以拦截对对象属性的所有访问企图,当属性被访问时,自动调用该方法(只适用于新式类).因此常用于实现一些访问某属性时执行一段代码的特性. 需 ...
- java多线程-cas及atomic
大纲: cas atomic 一.cas cas:compareAndSwap,一种乐观锁. cas思想:cas需要三个值,v是内存值,e是期望值,n是要修改的值.当内存中的值v等于预期值e(说明内存 ...
- spring data jpa 动态查询(工具类封装)
利用JPA的Specification<T>接口和元模型就实现动态查询了.但是这样每一个需要动态查询的地方都需要写一个这样类似的findByConditions方法,小型项目还好,大型项目 ...
- ngx.location.capture 只支持相对路径,不能用绝对路径
ngx.location.capture 是非阻塞的,ngx.location.capture也可以用来完成http请求,但是它只能请求到相对于当前nginx服务器的路径,不能使用之前的绝对路径进行访 ...
- 九度oj 1032 ZOJ 2009年浙江大学计算机及软件工程研究生机试真题
题目1032:ZOJ 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:4102 解决:2277 题目描述: 读入一个字符串,字符串中包含ZOJ三个字符,个数不一定相等,按ZOJ的顺序输出,当 ...
- 关于Map集合的遍历总结
Map集合的遍历经常遇到,今天在这里总结一下Map集合遍历的几种方式: public static void main(String[] args){ Map<String,String> ...
- pyquery库简介
html = '''<div><ul><li class="item-0">li0</li><li class="i ...