从异步服务更新视图

时间:2013-08-13 12:13:25

标签: c# wpf mvvm datagrid

我面临以下情况:

我的应用程序包含大量信息(存储在类中),用户可以搜索特定单词的信息(类似于Windows中的文件搜索)。

用户点击搜索按钮后,搜索应以异步方式开始,并在后台收集结果。搜索过程可能需要很长时间。假设处理搜索的类称为SearchService(SearchService.cs)。

用户可以在搜索服务正常工作时打开结果视图,其中包含需要在找到更多结果时更新结果的数据网格。

基本上是这样的:

服务是异步收集信息 - >视图模型应该获得已经存在的结果,并且应该通知新结果 - >带有datagrid的视图应该异步更新

我该如何实现?假设View Model向视图公开了一个ObservableCollection,但该如何从服务中更新该集合呢?

我正在使用Prism和MEF。

2 个答案:

答案 0 :(得分:0)

在结果的Binding对象中,设置此额外的IsAsync属性:

"{Binding PropertyName, IsAsync=True}"

接下来,在您的视图模型中添加如下方法:

public object RunOnUiThread(Delegate method)
{
    return Dispatcher.Invoke(DispatcherPriority.Normal, method);
}

现在您可以使用适合您需要的任何参数创建一个回调处理程序委托,并像这样异步调用您的服务:

Model.GetResultsAsync(GotResultsCallbackHandler);

服务可以存储对回调处理程序的引用,并在有更多结果时调用它。再次在您的视图模型中,您可以获得这样的结果,确保在UI线程上更新UI:

RunOnUiThread((Action)delegate
{
    ResultsCollection.AddRange(results);
});

这是一种伪代码......请问你是否理解。

答案 1 :(得分:0)

您可以使用Reactive Extensions(Rx)来实现此目的。

您的服务可以公开一个方法,该方法返回收集结果的IObservable。然后,您的服务可以在此IObservable上发布结果,因为服务会收集结果。并且,您的ViewModel可以订阅此IObservable并在结果到达ObservableCollection时更新IObservable

伪码如下:

服务类:

public class Service
{
    public IObservable<Result> GetResults()
    {
        //...
    }
}

ViewModel类:

public class ViewModel
{
    public ViewModel(Service service)
    {
        service.GetResults().Subscribe(x => Results.Add(x));
    }

    public ObservableCollection<Result> Results { get; set; }
}

Link to read about Rx