dialog now returns from showdialogasync when closed from overlay/button
MODIFY
WalletWasabi.Fluent/ViewModels/Dialog/DialogViewModelBaseOfTResult.cs
WalletWasabi.Fluent/ViewModels/Dialog/DialogViewModelBaseOfTResult.cs
using System;
+using System.Reactive.Linq;
using System.Threading.Tasks;
+using ReactiveUI;
namespace WalletWasabi.Fluent.ViewModels.Dialog
{
@@ -9,14 +11,48 @@ namespace WalletWasabi.Fluent.ViewModels.Dialog
/// <typeparam name="TResult">The type of the value to be returned when the dialog is finished.</typeparam>
public abstract class DialogViewModelBase<TResult> : DialogViewModelBase
{
+ protected DialogViewModelBase()
+ {
+ this.WhenAnyValue(x => x.IsDialogOpen)
+ .DistinctUntilChanged()
+ .Subscribe(OnIsDialogOpenChanged);
+ }
+
+ private void OnIsDialogOpenChanged(bool obj)
+ {
+ // Trigger when closed abruptly (via the Overlay or the back button).
+ if (!obj & CurrentTaskCompletionSource is { } & !DialogReturnedWithValue)
+ {
+ Close();
+ }
+ }
+
private TaskCompletionSource<TResult> CurrentTaskCompletionSource { get; set; }
+ /// <summary>
+ /// Method to be called when the dialog intends to close
+ /// without returning a value.
+ /// </summary>
+ protected void Close()
+ {
+ if (CurrentTaskCompletionSource is null)
+ {
+ throw new InvalidOperationException("CloseDialog with value return method failed due to missing TCS.");
+ }
+
+ CurrentTaskCompletionSource.SetResult(default);
+ CurrentTaskCompletionSource = null;
+ IsDialogOpen = false;
+
+ OnDialogClosed();
+ }
+
/// <summary>
/// Method to be called when the dialog intends to close
/// and ready to pass a value back to the caller.
/// </summary>
/// <param name="value">The return value of the dialog</param>
- public void CloseDialog(TResult value)
+ protected void Close(TResult value)
{
if (CurrentTaskCompletionSource is null)
{
@@ -25,8 +61,10 @@ namespace WalletWasabi.Fluent.ViewModels.Dialog
CurrentTaskCompletionSource.SetResult(value);
CurrentTaskCompletionSource = null;
+ DialogReturnedWithValue = true;
+ IsDialogOpen = false;
- CloseDialog();
+ OnDialogClosed();
}
/// <summary>
@@ -35,8 +73,6 @@ namespace WalletWasabi.Fluent.ViewModels.Dialog
/// <returns>The value to be returned when the dialog is finished.</returns>
public Task<TResult> ShowDialogAsync(IDialogHost host)
{
- host.CurrentDialog = this;
-
if (CurrentTaskCompletionSource is { })
{
throw new InvalidOperationException("Can't open a new dialog since there's already one active.");
@@ -44,7 +80,9 @@ namespace WalletWasabi.Fluent.ViewModels.Dialog
CurrentTaskCompletionSource = new TaskCompletionSource<TResult>();
+ host.CurrentDialog = this;
IsDialogOpen = true;
+ DialogReturnedWithValue = false;
return CurrentTaskCompletionSource.Task;
}

MODIFY
WalletWasabi.Fluent/Views/TestDialogView.axaml
WalletWasabi.Fluent/Views/TestDialogView.axaml
mc:Ignorable="d" Width="450" Height="200"
x:Class="WalletWasabi.Fluent.Views.TestDialogView">
<Panel Margin="10">
- <Button Classes="invisible" Command="{Binding CloseDialog}" HorizontalAlignment="Left" VerticalAlignment="Top">
+ <Button Classes="invisible" Command="{Binding Close}" HorizontalAlignment="Left" VerticalAlignment="Top">
<PathIcon Data="{StaticResource arrow_left_regular}" />
</Button>
<StackPanel HorizontalAlignment="Center"

dialog now returns from showdialogasync when closed from overlay/button