C# 在后台工作程序的RunWorkerCompleted事件期间,绑定到viewmodel属性的标签内容不会更新

C# 在后台工作程序的RunWorkerCompleted事件期间,绑定到viewmodel属性的标签内容不会更新,c#,wpf,mvvm,C#,Wpf,Mvvm,我在视图模型中使用后台工作人员查看了UI更新的几个线程,并根据需要对代码进行了更改,不幸的是,我无法使其正常工作 我正在尝试更新绑定到在视图模型中实现INotifyPropertyChanged的属性的标签内容。报告已创建,但更新的标签内容仅在从主WindowViewModel重新打开MyWindow时显示 MainWindow.xaml.cs public partial class MainWindow : Window { public MainWindow() {

我在视图模型中使用后台工作人员查看了UI更新的几个线程,并根据需要对代码进行了更改,不幸的是,我无法使其正常工作

我正在尝试更新绑定到在视图模型中实现INotifyPropertyChanged的属性的标签内容。报告已创建,但更新的标签内容仅在从主WindowViewModel重新打开MyWindow时显示

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();        

        Messenger.Default.Register<NotificationMessage>(this, 
            NotificationMessageReceived);

        Closing += (s, e) => ViewModelLocator.Cleanup();
    }

    private void NotificationMessageReceived(NotificationMessage msg)
    {      
        if (msg.Notification == "ShowMyWindow")
        {
            MyWindow ReportWind = new MyWindow();
            ReportWind.DataContext = msg.Sender;
            MyWindow.ShowDialog();
        }
    }
}
public class MyViewModel
{      
    //Fields 
    public static string statusProp = string.Empty;
    BackgroundWorker _BWorker = new BackgroundWorker();

    //Properties

    public string LblStatusContent
    {
        get
        {
            return statusProp;
        }
        set
        {
            statusProp = value;
            // Call OnPropertyChanged whenever the property is updated
            OnPropertyChanged("LblStatusContent");
        }
    }

    public RelayCommand GoCmd { get; private set; }

    public MyViewModel(IDialogService dService)
    {
        _dialogService = dService;
        GoCmd = new RelayCommand(() => Go(_dialogService), () => true);
    }

    private void Go(IDialogService dService)
    {
        //dialogservice to show a savedialogbox
        //do something.

        //start my thread to save a pdf refort
        _BWorker = new BackgroundWorker()
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };


        _BWorker.DoWork += new DoWorkEventHandler(DoWork);
        _BWorker.ProgressChanged += new      
            ProgressChangedEventHandler(WorkerProgress);
        _BWorker.RunWorkerCompleted += new 
        RunWorkerCompletedEventHandler(WorkerCompleted);

        if (_BWorker.IsBusy !=true)
        { 
            _BWorker.RunWorkerAsync();                        
        }
    }

    private void WorkerProgress(object sender, ProgressChangedEventArgs e)
    {
        try
        {
            if (e.UserState != null && e.UserState.ToString() != "")
            {
                // LblStatusContent =   
                //((ReportWindow.ReportProgressArg)e.UserState).smsg;
                //BatchCompareProgressBar.Value = e.ProgressPercentage;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            ErrorLogger.Log(LogLevel.Error, ex.ToString());
        }
    }

    private void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        try
        {
            if ((e.Cancelled == true))
            {
                this.LblStatusContent = "Cancelled";
            }
            else if (!(e.Error == null))
            {
                LblStatusContent = "Failed to create report";
                OnPropertyChanged(LblStatusContent);
                LblStatusVisibility = System.Windows.Visibility.Visible;
            }
            else
            {
                System.Windows.Application.Current.Dispatcher.Invoke(
                    DispatcherPriority.Normal,
                    (Action)delegate()
                        {
                            this.LblStatusContent = "Report created successfully";
                            OnPropertyChanged(LblStatusContent);
                            LblStatusVisibility = System.Windows.Visibility.Visible;
                        });
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            ErrorLogger.Log(LogLevel.Error, ex.ToString());
        }
    }

    private void DoWork(object sender, DoWorkEventArgs e)
    {
        try
        {
            StartReport();                
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
            ErrorLogger.Log(LogLevel.Error, ex.ToString());
        }
        finally { }
    }
}
MyWindow.xaml

<Label Name="lblStatus" VerticalAlignment="Center" 
       Content="{Binding LblStatusContent}" 
       Visibility="{Binding LblStatusVisibility, Mode=TwoWay}" 
       Margin="0,80,12,203" Height="36" 
       HorizontalAlignment="Right" Width="450" />

也许这个小例子能帮你解决这个问题

<Window x:Class="WpfApplication1.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication1.ViewModel"
        Title="MainWindow"
        Height="80"
        Width="140">

    <Window.DataContext>
      <viewModel:MainViewModel />
    </Window.DataContext>

    <Label Content="{Binding Property}" />
</Window>


namespace WpfApplication1.ViewModel
{
公共类MainViewModel:ViewModelBase
{
readonly BackgroundWorker _worker=新BackgroundWorker();
私有字符串属性;
公共主视图模型()
{
_worker.WorkerReportsProgress=true;
_worker.DoWork+=(发送方,参数)=>
{
int迭代次数=0;
属性=“开始…”;
睡眠(1000);
而(迭代次数<5次)
{
_工人进度报告(迭代次数*25);
迭代++;
睡眠(350);
}
};
_worker.ProgressChanged+=(发送方,参数)=>
Property=string.Format(“Working…{0}%”,args.ProgressPercentage);
_worker.RunWorkerCompleted+=(发送方,参数)=>
{
Property=“完成!”;
};
_worker.RunWorkerAsync();
}
公共字符串属性
{
获取{return\u property;}
设置{u property=value;RaisePropertyChanged();}
}
}
}

也许这个小例子能帮你解决这个问题

<Window x:Class="WpfApplication1.View.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication1.ViewModel"
        Title="MainWindow"
        Height="80"
        Width="140">

    <Window.DataContext>
      <viewModel:MainViewModel />
    </Window.DataContext>

    <Label Content="{Binding Property}" />
</Window>


namespace WpfApplication1.ViewModel
{
公共类MainViewModel:ViewModelBase
{
readonly BackgroundWorker _worker=新BackgroundWorker();
私有字符串属性;
公共主视图模型()
{
_worker.WorkerReportsProgress=true;
_worker.DoWork+=(发送方,参数)=>
{
int迭代次数=0;
属性=“开始…”;
睡眠(1000);
而(迭代次数<5次)
{
_工人进度报告(迭代次数*25);
迭代++;
睡眠(350);
}
};
_worker.ProgressChanged+=(发送方,参数)=>
Property=string.Format(“Working…{0}%”,args.ProgressPercentage);
_worker.RunWorkerCompleted+=(发送方,参数)=>
{
Property=“完成!”;
};
_worker.RunWorkerAsync();
}
公共字符串属性
{
获取{return\u property;}
设置{u property=value;RaisePropertyChanged();}
}
}
}

我不知道我怎么会错过订阅类声明中的INotifyPropertychanged,即使我正确地实现了Onpropertychanged。 要在后台进程完成后窗口仍处于打开状态时更新属性,我只需执行以下操作:
公共类MainViewModel:ViewModelBase,INotifyPropertyChanged。

我不知道我怎么会错过订阅在类声明中更改的INotifyPropertyChanged,即使我正确实现了Onpropertychanged。 要在后台进程完成后窗口仍处于打开状态时更新属性,我只需执行以下操作:
公共类MainViewModel:ViewModelBase,InotifyProperty已更改。

我已更改InotifyProperty。在上一次测试中,我还将UpdateSourceTrigger=PropertyChanged添加到我的XAML中。它不起作用。我将再次添加该部分,并在稍后进行一些代码更改时重新测试。我使用了snoop,标签的content属性显示它绑定到了正确的属性,但未显示在UI上。@Mikko,是MVVM Light,WPF。我试过调度员助手。不起作用。我在App.xaml.cs的OnStartup()中初始化了它。并更新了代码DispatcherHelper.CheckBeginInvokeOnUI。DoWork已经工作,我希望runworkecompleted代码更新UI元素,表明报告已成功创建。@Mikko,这不起作用。我希望在创建报告后不会更新标签。我已更改InotifyProperty。在上一次测试中,我还将UpdateSourceTrigger=PropertyChanged添加到我的XAML中。它不起作用。我将再次添加该部分,并在稍后进行一些代码更改时重新测试。我使用了snoop,标签的content属性显示它绑定到了正确的属性,但未显示在UI上。@Mikko,是MVVM Light,WPF。我试过调度员助手。不起作用。我在App.xaml.cs的OnStartup()中初始化了它。并更新了代码DispatcherHelper.CheckBeginInvokeOnUI。DoWork已经工作了,我希望runworkecompleted代码更新UI元素,表明报告创建成功。@Mikko,这不起作用。我希望在创建报告后不会更新标签。经过多次尝试后,我没有让它工作。有人能给我指点迷津吗?经过无数次的尝试,我都没能成功。谁能指引我。