ReactiveUI 嵌套命令 IsExecuting 在 window 关闭之前不会更改

ReactiveUI nested Command IsExecuting does not change until window closes

为了演示,我有一个 window MainWindow,它带有一个按钮,单击时会打开一个对话框 Dialog。该对话框有一个按钮 Hello。单击 Hello 按钮时,将执行一个命令,等待 3 秒并显示一个带有消息“Hello, world!”的 MessagaBox。我订阅命令的 IsExecuting 并在获得值时显示它。问题是在我点击 Hello 按钮后,只有“Hello, world!”显示时,IsExecuting 值(“True”和“False”)在对话框(class Dialog)关闭之前不会显示。

主窗口:

<Window x:Class="WpfDemo.MainWindow"
        ...
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:MainViewModel x:Key="ViewModel"></local:MainViewModel>
    </Window.Resources>
    <Window.DataContext>
        <StaticResource ResourceKey="ViewModel"></StaticResource>
    </Window.DataContext>
    <Grid>
        <Button Name="ShowDialog" 
                Command="{Binding CommandShowDialog}">Show Dialog</Button>
    </Grid>
</Window>

主视图模型:

public class MainViewModel : ReactiveObject
{
    public ReactiveCommand<Unit,Unit> CommandShowDialog { get; set; }

    public MainViewModel()
    {
        CommandShowDialog = ReactiveCommand.Create(ShowDialog);
    }

    private void ShowDialog()
    {
        new Dialog().ShowDialog();
    }
}  

对话:

<Window x:Class="WpfDemo.Dialog"
        ...
        Title="Dialog" Height="450" Width="800">
    <Window.Resources>
        <local:DialogViewModel x:Key="vm"></local:DialogViewModel>
    </Window.Resources>
    <Window.DataContext>
        <StaticResource ResourceKey="vm"></StaticResource>
    </Window.DataContext>
    <Grid>
        <Button Name="Hello" Command="{Binding Command}">Hello, world!</Button>
    </Grid>
</Window>

DialogViewModel

public class DialogViewModel : ReactiveObject
{
    public ReactiveCommand<Unit, string> Command { get; set; }

    private readonly ObservableAsPropertyHelper<bool> _isExecuting;

    public bool IsExecuting => _isExecuting.Value;

    public DialogViewModel()
    {
        Command = ReactiveCommand.CreateFromTask(Hello);
        _isExecuting = Command.IsExecuting
            .ToProperty(this, x => x.IsExecuting);
        this.WhenAnyValue(x => x.IsExecuting)
            .Subscribe(b => MessageBox.Show(b.ToString()));
    }

    private async Task<string> Hello()
    {
        return await Task.Run(delegate
        {
            Thread.Sleep(3000);
            const string s = "Hello, world!";
            MessageBox.Show(s);
            return s;
        });
    }
}

ShowDialog() 阻塞直到对话框关闭。请改为调用 Show()