当需要用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. urllib和urllib3

    urllib库 urllib 是一个用来处理网络请求的python标准库,它包含4个模块. urllib.request---请求模块,用于发起网络请求 urllib.parse---解析模块,用于解 ...

  2. 使用Appium-Desktop捕获APP元素控件实现自动化控制

    使用Appium捕获APP的元素控件 实现自动化控制 我是用的是华为P20手机进行测试,为了映射出它的adb端口,需再去官网下载安装一个华为手机助手,然后将手机调成开发者模式,连接时选择传输文件模式. ...

  3. Vue生命周期钩子详解【个人解读】

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. C语言中结构体定义

    struct test { int a; }; /* 定义一个结构体,名字是test,这样就可以使用struct test 来定义变量.比如 struct test a; */ typedef str ...

  5. 2019.03.29 读书笔记 关于override与new

    差异:override:覆盖父类分方法,new 隐藏父类方法. 共同:都不能改变父类自身方法. public class Test { public string Name { get; set; } ...

  6. 彻底解决matplotlib中文乱码问题(转)

    彻底解决matplotlib中文乱码问题 1.环境查看a.系统版本查看[hadoop@p168 ~]$ cat /etc/redhat-releaseCentOS Linux release 7.2. ...

  7. selenium+Python(Page Object 设计模式实例)

    以下实例演示了采用了page Object设计模式的方式登录qq空间: 1.创建基础类page:在初始方法__init__()定义驱动的(driver),基本url(base_url)和超时时间(ti ...

  8. Cloudera Manager安装之时间服务器和时间客户端(Ubuntu14.04)(二)

    第二步: Cloudera Manager安装之时间服务器和时间客户端(二) 找一台机器作为时间服务器 我这里,放到ubuntucmbigdata1这台机器! 注意,之前是已经做了集群时间同步了. 在 ...

  9. DIV+CSS常见面试题

    1.!important拥有最高的优先级,几乎所有浏览器都支持!important,除了IE6(不完全支持) 例1(IE6支持,颜色为#e00): .cssClass{color:#e00!impor ...

  10. Django级联删除的选项

    Django级联删除的选项 Django模型中的on_delete属性具有如下选项: CASCADE 级联删除,也就是被引用的实体被删除后,相关的记录信息都会被删除. PROTECT 阻止删除被引用的 ...