79 lines
2.2 KiB
C#
79 lines
2.2 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using HandyControl.Controls;
|
|
|
|
namespace HandyControl.Tools.Extension
|
|
{
|
|
public interface IDialogResultable<T>
|
|
{
|
|
T Result { get; set; }
|
|
|
|
Action CloseAction { get; set; }
|
|
}
|
|
|
|
public static class DialogExtension
|
|
{
|
|
public static Task<TResult> GetResultAsync<TResult>(this Dialog dialog)
|
|
{
|
|
var tcs = new TaskCompletionSource<TResult>();
|
|
|
|
try
|
|
{
|
|
if (dialog.IsClosed)
|
|
{
|
|
SetResult();
|
|
}
|
|
else
|
|
{
|
|
dialog.Unloaded += OnUnloaded;
|
|
dialog.GetViewModel<IDialogResultable<TResult>>().CloseAction = dialog.Close;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
tcs.TrySetException(e);
|
|
}
|
|
|
|
return tcs.Task;
|
|
|
|
// ReSharper disable once ImplicitlyCapturedClosure
|
|
void OnUnloaded(object sender, RoutedEventArgs args)
|
|
{
|
|
dialog.Unloaded -= OnUnloaded;
|
|
SetResult();
|
|
}
|
|
|
|
void SetResult()
|
|
{
|
|
try
|
|
{
|
|
tcs.TrySetResult(dialog.GetViewModel<IDialogResultable<TResult>>().Result);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
tcs.TrySetException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Dialog Initialize<TViewModel>(this Dialog dialog, Action<TViewModel> configure)
|
|
{
|
|
configure?.Invoke(dialog.GetViewModel<TViewModel>());
|
|
|
|
return dialog;
|
|
}
|
|
|
|
public static TViewModel GetViewModel<TViewModel>(this Dialog dialog)
|
|
{
|
|
if (!(dialog.Content is FrameworkElement frameworkElement))
|
|
throw new InvalidOperationException("The dialog is not a derived class of the FrameworkElement. ");
|
|
|
|
if (!(frameworkElement.DataContext is TViewModel viewModel))
|
|
throw new InvalidOperationException($"The view model of the dialog is not the {typeof(TViewModel)} type or its derived class. ");
|
|
|
|
return viewModel;
|
|
}
|
|
}
|
|
}
|