忙碌指示器未显示在异步方法中

Busy indicator not showing in async method

我正在使用 Extended WPF Toolkit and MVVM Light 库。

我想实现 WPF 工具包忙碌指示器并定期通知用户一些信息(与视图模型中的 BusyMessage 属性 绑定)。

但是,当单击按钮 'Start' 时,忙碌指示器(IsBusy 绑定到视图模型中的 IsBusy 属性)不会显示。我做错了什么? 奇怪的是,当在视图模型的构造函数中将 IsBusy 设置为 true 时它会起作用。

App.xaml

public partial class App : Application
{
    public App()
    {
        DispatcherHelper.Initialize();
    }
}

Window

<Window xmlns:xctk='http://schemas.xceed.com/wpf/xaml/toolkit'
    DataContext='{Binding Main, Source={StaticResource Locator}}'>
 <StackPanel>
 <xctk:BusyIndicator IsBusy='{Binding IsBusy}'>
  <xctk:BusyIndicator.BusyContentTemplate>
    <DataTemplate>
      <StackPanel Margin='4'>
        <TextBlock Text='{Binding DataContext.BusyMessage, RelativeSource={RelativeSource AncestorType={x:Type Window}}}' />
      </StackPanel>
    </DataTemplate>
  </xctk:BusyIndicator.BusyContentTemplate>      
<Button Content='Start ...'
        Command='{Binding StartCommand}'
        HorizontalAlignment='Center'
        VerticalAlignment='Center' />
</xctk:BusyIndicator>

视图模型

public class MainViewModel : ViewModelBase
{
    private string _busyMessage;

    public string BusyMessage
    {
        get { return _busyMessage; }
        set
        {
            if (_busyMessage != value)
            {
                _busyMessage = value;
                RaisePropertyChanged(nameof(_busyMessage));
            }
        }
    }

    private bool _isBusy;

    public bool IsBusy
    {
        get { return _isBusy; }
        set {
            if (_isBusy != value)
            {
                _isBusy = value;
                RaisePropertyChanged(nameof(_isBusy));
            }
        }
    }

    public RelayCommand StartCommand
    {
        get { return new RelayCommand(() => StartExecute()); }
    }


    private async void StartExecute()
    {
        IsBusy = true;
        await Task.Run(() =>
        {
            //update UI from worker thread
            DispatcherHelper.CheckBeginInvokeOnUI(() => BusyMessage = "Work 1 Done");
            Thread.Sleep(1000);
            //update UI from worker thread
            DispatcherHelper.CheckBeginInvokeOnUI(() => BusyMessage = "Work 2 Done");
        });
        IsBusy = false;
    }

    public MainViewModel()
    {
        //Works when boolean is set to 'true' in constructor
        //IsBusy = true;
    }
}

这正是我更喜欢 ReactiveUI 的原因 - 它在 ReactiveCommand 中内置了 "busy indicator",甚至是异步的。

至于你的问题,我会说你的RaisePropertyChanged(nameof(_isBusy));是错误的,应该是RaisePropertyChanged(nameof(IsBusy)); // name of the public property

此外,根据您的 RaisePropertyChanged 实现,您可以适当地将参数留空,只使用 RaisePropertyChanged();