当需要用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 和 实时刷新的更多相关文章

  1. 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令

    [源码下载] 背水一战 Windows 10 (24) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过非 ButtonBase 触发命令 作者:webabcd ...

  2. 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令

    [源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd ...

  3. 使用SignalR实现比特币价格实时刷新

    ASP.NET SignalR是微软支持的一个运行在 Dot NET 平台上的 HTML Websocket 框架.它出现的主要目的是实现服务器主动推送(Push)消息到客户端页面,这样客户端就不必重 ...

  4. Sublime Text 3配置LiveReload实现实时刷新

    今天看到一款很强大的插件,LiveReload,实时刷新,也就是说写完html/css/js等不用再到浏览器里按F5啦,在Ctrl+S时浏览器会自动刷新,是不是想想都很爽... Chrome:(据说支 ...

  5. Gulp-livereload:实时刷新编码

    实现功能 监听指定目录下的所有文件,实时动态刷新页面 安装(Install) 功能的实现是借助 gulp-connect 插件完成的;所以,首先通过下面命令完成插件安装: npm install -- ...

  6. tab栏切换,内容为不断实时刷新数据的vue实现方法

    先说一下产品需求,就是有几个tab栏,每个tab栏对应的ajax请求不一样,内容区域一样,内容为实时刷新数据,每3s需要重新请求,返回的数据在内容区域展示,每点击一次tab栏需停止其他tab栏ajax ...

  7. webpack-dev-server 搭建本地服务以及浏览器实时刷新

    一.概述开发项目中为了保证上线,开发项目是都需要使用localhost进行开发,以前的做法就是本地搭建Apache或者Tomcat服务器.有的前端开发人员 对服务器的搭建和配置并不熟悉,这个时候需要后 ...

  8. JAVAFX之tableview界面实时刷新导致的内存溢出(自己挖的坑,爬着也要出来啊0.0)

    这几天遇到了一个问题,不幸开发的一个cs架构的工具,客户端开启后,内存一直在缓慢增长最终导致进程卡死,花了4天时间,终于爬出来了... 客户端通过timer定时器每30秒查询一次数据库以及一些业务逻辑 ...

  9. js获取当前时间并实时刷新

    效果如图: 代码如下: <html> <head> <title>js获取当前时间并实时刷新</title> <script> //页面加载 ...

随机推荐

  1. 项目Alpha冲刺 6

    作业描述 课程: 软件工程1916|W(福州大学) 作业要求: 项目Alpha冲刺(团队) 团队名称: 火鸡堂 作业目标: 介绍第6天冲刺的项目进展.问题困难和心得体会 1.团队信息 队名:火鸡堂 队 ...

  2. SQL语句之数据库操作

    SQL语句系列 1.SQL语句之行操作 2.SQL语句之表操作 3.SQL语句之数据库操作 4.SQL语句之用户管理 占坑,带写……

  3. [Ruby]Unzipping a file using rubyzip

    link: http://www.markhneedham.com/blog/2008/10/02/ruby-unzipping-a-file-using-rubyzip/ require 'ruby ...

  4. JavaWeb学习笔记(二十一)—— 监听器Listener

    一.监听器概述 JavaWeb中的监听器是Servlet规范中定义的一种特殊类,它用于监听web应用程序中的ServletContext, HttpSession和 ServletRequest等域对 ...

  5. docker 查看容器信息---格式化

    镜像,ID,端口号,状态 docker ps -a --format "table {{.Image}}\t{{.ID}}\t{{.Ports}}\t{{.Status}}" 列出 ...

  6. 基于iTop4412的FM收音机系统设计(一)

    说明:第一版架构为:APP+JNI(NDK)+Driver(linux),优点是开发简单,周期短,也作为自己的毕业设计 现在更新第二版,FM服务完全植入Android系统中,成为系统服务,架构为:AP ...

  7. java设计模式学习笔记

    简介 设计模式可以分为五类 接口型 模式:适配器模式,外观模式,合成模式,桥接模式 职责型 模式:单例模式,观察者模式,调停者模式,代理模式,职责链模式,享元模式 构造型 模式:构建者模式,工厂方法模 ...

  8. nodejs的process.on('message')转promise

    // main.js const cp = require('child_process'); const child = cp.fork('./child.js'); const callbackP ...

  9. mysql故障总结

    MYSQL故障排查 https://zhuanlan.zhihu.com/p/27834293

  10. Java学习之路(三):Java中的数组

    数组的概述和定义的格式 数组的作用: 用来存储同种数据类型的多个值 数组的基本概念: 数组是存储同一种数据类型多个元素的集合.就相当于一个容器. 注意:数组既可以存储基本数据类型,也可以存储引用数据类 ...