【问题标题】:Refresh DataGrid from worker thread从工作线程刷新 DataGrid
【发布时间】:2015-05-10 08:29:05
【问题描述】:

我的 WPF 应用程序中有一个 DataGrid。对于这个 DataGrid,我将 ItemSource 设置如下

ItemsSource="{Binding Path=MyItems}"

MyItems 是 MyViewModel 中声明的 MyItem 列表

    // ItemsSource for MyItem Grid
    public List<MyItem> MyItems {get;set; }

MyItem 具有一组属性,每个属性都映射到 DataGrid 中的每一列。在初始化时,我正在填写 MyItems;所以 DataGrid 在每一列中显示 MyItems 值。

在一个按钮命令中,我正在创建一个工作线程,工作线程修改 MyItems 的属性,这些属性显示在网格中。例如,MyItem 有一个名为“Status”的属性,它绑定到网格列。状态值在工作线程中更改。我正在调用的工作线程结束

OnPropertyChanged("MyItems"); //force UI refresh

但网格中的状态列值没有更新。

单击数据网格列后,只有值会刷新。如何从工作线程刷新数据网格?

【问题讨论】:

  • 显示MyItem 的代码。这需要是可观察的。 (另外,通知需要在 UI 线程中发送。

标签: c# wpf datagrid worker-thread


【解决方案1】:

如果你做对了,你就不需要告诉网格刷新。如果您确实设法刷新了整个网格,也会产生意想不到的后果,例如跳到网格顶部并丢失任何用户选择的行/单元格,以及在适用的情况下中止编辑。

ObservableCollection

这是您应该如何设置网格正在查看的列表:

private readonly ObservableCollection<MyItem> _myItems = new ObservableCollection<MyItem>();

public IEnumerable<MyItem> MyItems { get { return _myItems; } }

这意味着新项目和删除会自动更新网格。但是,要更新单个单元格,该属性需要是可观察的,即 MyItem 类必须实现 INotifyPropertyChanged

多线程

对于多线程,您需要在 UI 线程中设置 MyItem 的属性,即使您在工作线程中进行计算(见下文)。您可以通过Dispatcher 实现此目的。见Updating GUI (WPF) using a different thread

工作线程

至于开始你自己的线程,不要那样做,使用Task

【讨论】:

  • 非常好。也可能出书了:)
【解决方案2】:

使用调度程序不是一个好主意。如果编码不正确,UI 可能会变得无响应。在多线程环境中使用数据网格很棘手。

  1. 后台线程处理数据并基于此结果 处理,数据网格将被更新。
  2. WPF 中的 UI 控件只能由 UI 线程更新。
  3. 可以有多个 UI 控件协同工作 实现整体功能(进度条、按钮等)。 编码人员经常在传递控制引用时犯错误 不安全的方式。
  4. 数据网格将绑定到的数据源不应是 可由任何其他类修改。

我在这里发布了一个模板。它涵盖了在多线程设置中使用数据网格的可能方法。

http://www.codeproject.com/Articles/1086714/A-Template-For-Using-Datagrid-in-Monitoring-UI

【讨论】:

    猜你喜欢
    • 2013-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多