当需要用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. Angular material mat-icon 资源参考_Communication

    ul,li>ol { margin-bottom: 0 } dt { font-weight: 700 } dd { margin: 0 1.5em 1.5em } img { height: ...

  2. Android Studio Gradle下载的包在哪里?

    C:\Users\Administrator\.gradle\caches\modules-2\files-2.1

  3. (转)C++ main函数中参数argc和argv含义及用法

    原博地址:https://blog.csdn.net/dcrmg/article/details/51987413 argc 是 argument count的缩写,表示传入main函数的参数个数: ...

  4. shiyan 3

    //info.h#ifndef INFO_H #define INFO_H #include <string> using std::string; class Info { public ...

  5. (转)虚拟路由器冗余协议【原理篇】VRRP详解

    原文:http://blog.51cto.com/zhaoyuqiang/1166840 为什么要使用VRRP技术 我们知道,为了实现不同子网之间的设备通信,需要配置路由.目前常用的指定路由方法有两种 ...

  6. 如何获取用户的地理位置? && html5 地理位置

    推荐网站 https://html5demos.com/geo/ 我们有时候可能希望首先获得用户的地理位置,然后根据不同的地理位置(更具针对性地)推送不同的信息等等. 下面这段代码就可以在你有jQue ...

  7. Python openpyxl Read

    #! /usr/bin/env python # coding=utf-8 from openpyxl import Workbook, load_workbook wb = load_workboo ...

  8. 参数化登录QQ空间实例

    通过参数化的方式,登录QQ空间 实例源码: # coding:utf-8 from selenium import webdriver import unittest import time clas ...

  9. c++ 常用的遍历,删除,分割等等文件处理函数代码实现

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/9622851.html 删除文件目录函数: void myDeleteDirectory(CSt ...

  10. plsql数据库异常---plsql 登录后,提示数据库字符集(AL32UTF8)和客户端字符集(ZHS16GBK)不一致

    今天遇到这个问题网上搜了一下答案找到了 转贴 http://blog.csdn.net/lidew521/article/details/8546155 plsql 登录后提示: Database c ...