确保在 MVVM WPF 应用程序的 UI 线程上调用 OnPropertyChanged() [英] Making sure OnPropertyChanged() is called on UI thread in MVVM WPF app

查看:21
本文介绍了确保在 MVVM WPF 应用程序的 UI 线程上调用 OnPropertyChanged()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我使用 MVVM 模式编写的 WPF 应用程序中,我有一个后台进程在做它的事情,但需要从它获取状态更新到 UI.

In a WPF app that I'm writing using the MVVM pattern, I have a background process that doing it's thing, but need to get status updates from it out to the UI.

我使用的是 MVVM 模式,因此我的 ViewModel 几乎不知道向用户呈现模型的视图 (UI).

I'm using the MVVM pattern, so my ViewModel knows virtually nothing of the view (UI) that is presenting the model to the user.

假设我的 ViewModel 中有以下方法:

Say I have the following method in my ViewModel:

public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
    this.Messages.Add(e.Message);
    OnPropertyChanged("Messages");
}

在我看来,我有一个绑定到 ViewModel 的 Messages 属性(List)的 ListBox.OnPropertyChanged 通过调用 PropertyChangedEventHandler 来实现 INotifyPropertyChanged 接口的作用.

In my view, I have a ListBox bound to the Messages property (a List<string>) of the ViewModel. OnPropertyChanged fulfills the role of the INotifyPropertyChanged interface by calling a PropertyChangedEventHandler.

我需要确保在 UI 线程上调用 OnPropertyChanged - 我该怎么做?我尝试了以下方法:

I need to ensure that OnPropertyChanged is called on the UI thread - how do I do this? I've tried the following:

public Dispatcher Dispatcher { get; set; }
public MyViewModel()
{ 
    this.Dispatcher = Dispatcher.CurrentDispatcher;
}

然后将以下内容添加到 OnPropertyChanged 方法中:

Then adding the following to the OnPropertyChanged method:

if (this.Dispatcher != Dispatcher.CurrentDispatcher)
{
    this.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadStart(delegate
    {
        OnPropertyChanged(propertyName);
    }));
    return;
}

但这没有用.有什么想法吗?

but this did not work. Any ideas?

推荐答案

WPF 自动将属性更改封送至 UI 线程.但是,它不会封送集合更改,因此我怀疑您添加的消息会导致失败.

WPF automatically marshals property changes to the UI thread. However, it does not marshal collection changes, so I suspect your adding a message is causing the failure.

您可以自己手动编组添加(参见下面的示例),或使用类似 这项技术 我在不久前写过博客.

You can marshal the add manually yourself (see example below), or use something like this technique I blogged about a while back.

手动编组:

public void backgroundWorker_ReportProgress(object sender, ReportProgressArgs e)
{
    Dispatcher.Invoke(new Action<string>(AddMessage), e.Message);
    OnPropertyChanged("Messages");
}

private void AddMessage(string message)
{
    Dispatcher.VerifyAccess();
    Messages.Add(message);
}

这篇关于确保在 MVVM WPF 应用程序的 UI 线程上调用 OnPropertyChanged()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆