For demonstration, I have a window MainWindow
with a button that open a dialog Dialog
when clicked. The dialog has a button Hello
. When the Hello
button is clicked, a command will execute, which wait 3s and show a MessagaBox with message "Hello, world!". I subscribe to the command's IsExecuting and display it when I get a value. The problem is that after I click the Hello
button, only "Hello, world!" is displayed, the IsExecuting value("True" and "False") is not displayed until the dialog(class Dialog
) closes.
MainWindow:
<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>
MainViewModel:
public class MainViewModel : ReactiveObject
{
public ReactiveCommand<Unit,Unit> CommandShowDialog { get; set; }
public MainViewModel()
{
CommandShowDialog = ReactiveCommand.Create(ShowDialog);
}
private void ShowDialog()
{
new Dialog().ShowDialog();
}
}
Dialog:
<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;
});
}
}
CodePudding user response:
ShowDialog()
blocks the until the dialog is closed. Call Show()
instead.