【问题标题】:Updating ObservableCollection from another class从另一个类更新 ObservableCollection
【发布时间】:2016-08-01 12:39:09
【问题描述】:

我有一个绑定到 DataGrid 的 ObservableCollection。我想更新另一个运行异步函数的类中的集合。目前,当我尝试正常添加它时,我收到错误:This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread。阅读其他问题,许多人建议使用BindingOperations.EnableCollectionSynchronization,但我不知道如何实现它,也找不到任何从另一个类运行它的示例。这是更新集合的正确方法,因为它们会非常频繁地更新,还是有更好的方法?

至于代码,主类:

public DataStore dataStore = new DataStore();
public MainWindow() {

 InitializeComponent();
 requestView.ItemsSource = dataStore.requestData;
 responseView.ItemsSource = dataStore.responseData;

 DataRetriver drt = new DataRetriver(dataStore);
}

以及检索数据的类:

public class DataRetriver 
{
 DataStore localStore;
 public BidAskDataRetriver(DataStore ds) 
 {
  this.localStore = ds;
  runA();
 }

 public void runA() 
 {
  //Build listener
  listener.Bind("data", (dynamic data) => {
   //data = json
   parseData(data);
  });
 }

 parseData(dynamic data) 
 {
  //parse data and make a list with items for collection
  foreach(myClass item in items)
   localStore.requestData.Add(item);
 }
}

【问题讨论】:

标签: wpf .net-4.5


【解决方案1】:

您可以使用 Dispatcher 来执行此操作。要使用调度程序,您必须保留一个 Dispatcher 实例。例如,您可以像这样通过类构造函数发送 UI 调度程序并将其存储在“调度程序”中:

DataRetriver drt = new DataRetriver(dataStore, requestView.Dispatcher);

然后下面的代码将完成这项工作,但要知道这一点,Dispatcher 任务在 UI 线程上运行,因此您发送给 Dispatcher 的操作越多,您在不同线程中执行的后台进程就越少,用处就越小。因此,您可能会考虑在后台的另一个对象中创建您的列表,并一步(而不是循环)将其设置为原始对象。

 parseData(dynamic data) 
 {
   //parse data and make a list with items for collection
   foreach(myClass item in items)
   {
      dispatcher.Invoke(()=>{
         localStore.requestData.Add(item);
      });
   }
 }

【讨论】:

    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2015-08-22
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多