diff --git a/src/Forms/Prism.Forms/Dialogs/DialogService.cs b/src/Forms/Prism.Forms/Dialogs/DialogService.cs index 2a0a733e59649ca89150dd3ad375a9c26e6fb55c..ce4e65cc91b6689b33bbe535eb08ed75a3001fac 100644 --- a/src/Forms/Prism.Forms/Dialogs/DialogService.cs +++ b/src/Forms/Prism.Forms/Dialogs/DialogService.cs @@ -49,11 +49,11 @@ namespace Prism.Dialogs dialogAware.RequestClose = new(DialogAware_RequestClose); - async Task DialogAware_RequestClose(IDialogParameters outParameters) + async Task DialogAware_RequestClose(IDialogResult outResult) { try { - var result = await CloseDialogAsync(outParameters ?? new DialogParameters(), currentPage, dialogModal); + var result = await CloseDialogAsync(outResult ?? new DialogResult(), currentPage, dialogModal); dialogModal.RaiseDialogResult(result); if (result.Exception is DialogException de && de.Message == DialogException.CanCloseIsFalse) { @@ -110,15 +110,21 @@ namespace Prism.Dialogs } } - private async System.Threading.Tasks.Task CloseDialogAsync(IDialogParameters parameters, ContentPage currentPage, DialogPage dialogModal) + private async System.Threading.Tasks.Task CloseDialogAsync(IDialogResult result, ContentPage currentPage, DialogPage dialogModal) { try { PageNavigationService.NavigationSource = PageNavigationSource.DialogService; - if (parameters is null) + result ??= new DialogResult(); + if (result.Parameters is null) { - parameters = new DialogParameters(); + result = new DialogResult + { + Exception = result.Exception, + Parameters = new DialogParameters(), + Result = result.Result + }; } var view = dialogModal.DialogView; @@ -135,10 +141,7 @@ namespace Prism.Dialogs PageUtilities.InvokeViewAndViewModelAction(currentPage, aa => aa.IsActive = true); dialogAware.OnDialogClosed(); - return new DialogResult - { - Parameters = parameters - }; + return result; } catch (DialogException) { @@ -149,7 +152,8 @@ namespace Prism.Dialogs return new DialogResult { Exception = ex, - Parameters = parameters + Parameters = result.Parameters, + Result = result.Result }; } finally @@ -246,7 +250,7 @@ namespace Prism.Dialogs } } - private async void InsertPopupViewInCurrentPage(ContentPage currentPage, DialogPage modalPage, View popupView, bool hideOnBackgroundTapped, DialogCloseEvent closeEvent) + private async void InsertPopupViewInCurrentPage(ContentPage currentPage, DialogPage modalPage, View popupView, bool hideOnBackgroundTapped, DialogCloseCallback closeEvent) { View mask = DialogLayout.GetMask(popupView); diff --git a/src/Maui/Prism.Maui/Dialogs/DialogService.cs b/src/Maui/Prism.Maui/Dialogs/DialogService.cs index f17440ff7c09050e8750324d692ad8a7e068bec1..e70333957aa54bcd730589a05ce31d31f53943a5 100644 --- a/src/Maui/Prism.Maui/Dialogs/DialogService.cs +++ b/src/Maui/Prism.Maui/Dialogs/DialogService.cs @@ -14,12 +14,19 @@ public sealed class DialogService : IDialogService private readonly IContainerProvider _container; private readonly IPageAccessor _pageAccessor; + /// + /// Creates a new instance of the for Maui Applications + /// + /// The that will be used to help resolve the Dialog Views. + /// The used to determine where in the Navigation Stack we need to process the Dialog. + /// Throws when any constructor arguments are null. public DialogService(IContainerProvider container, IPageAccessor pageAccessor) { _container = container ?? throw new ArgumentNullException(nameof(container)); _pageAccessor = pageAccessor ?? throw new ArgumentNullException(nameof(pageAccessor)); } + /// public void ShowDialog(string name, IDialogParameters parameters, DialogCallback callback) { try @@ -35,11 +42,11 @@ public sealed class DialogService : IDialogService var dialogModal = _container.Resolve(); var dialogAware = GetDialogController(view); - async Task DialogAware_RequestClose(IDialogParameters outParameters) + async Task DialogAware_RequestClose(IDialogResult outResult) { try { - var result = await CloseDialogAsync(outParameters ?? new DialogParameters(), currentPage, dialogModal); + var result = await CloseDialogAsync(outResult ?? new DialogResult(), currentPage, dialogModal); if (result.Exception is DialogException de && de.Message == DialogException.CanCloseIsFalse) { return; @@ -53,7 +60,8 @@ public sealed class DialogService : IDialogService var result = new DialogResult { Exception = dex, - Parameters = parameters + Parameters = parameters, + Result = ButtonResult.None }; if (dex.Message != DialogException.CanCloseIsFalse) @@ -100,18 +108,28 @@ public sealed class DialogService : IDialogService var result = new DialogResult { Parameters = parameters, - Exception = exception + Exception = exception, + Result = ButtonResult.None }; await callback.Invoke(result); } - private static async Task CloseDialogAsync(IDialogParameters parameters, Page currentPage, IDialogContainer dialogModal) + private static async Task CloseDialogAsync(IDialogResult result, Page currentPage, IDialogContainer dialogModal) { try { PageNavigationService.NavigationSource = PageNavigationSource.DialogService; - parameters ??= new DialogParameters(); + result ??= new DialogResult(); + if (result.Parameters is null) + { + result = new DialogResult + { + Exception = result.Exception, + Parameters = new DialogParameters(), + Result = result.Result + }; + } var view = dialogModal.DialogView; var dialogAware = GetDialogController(view); @@ -129,10 +147,7 @@ public sealed class DialogService : IDialogService MvvmHelpers.InvokeViewAndViewModelAction(currentPage, aa => aa.IsActive = true); dialogAware.OnDialogClosed(); - return new DialogResult - { - Parameters = parameters - }; + return result; } catch (DialogException) { @@ -143,7 +158,8 @@ public sealed class DialogService : IDialogService return new DialogResult { Exception = ex, - Parameters = parameters + Parameters = result.Parameters, + Result = result.Result }; } finally diff --git a/src/Prism.Core/Dialogs/DialogCloseCallback.cs b/src/Prism.Core/Dialogs/DialogCloseCallback.cs new file mode 100644 index 0000000000000000000000000000000000000000..d8e1a250f8f371d7e10640b2dc46c1d952f3a4ed --- /dev/null +++ b/src/Prism.Core/Dialogs/DialogCloseCallback.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel; +using System.Threading.Tasks; + +#nullable enable +namespace Prism.Dialogs; + +/// +/// This is set by the on your ViewModel. This can then +/// be invoked by either the DialogService or your code to initiate closing the Dialog. +/// +public struct DialogCloseCallback +{ + private readonly MulticastDelegate _callback; + + /// + /// Creates a default instance of the + /// + public DialogCloseCallback() + { + _callback = () => { }; + } + + /// + /// Creates an instance of the with an callback. + /// + /// The callback to invoke. + [EditorBrowsable(EditorBrowsableState.Never)] + public DialogCloseCallback(Action callback) + { + _callback = callback; + } + + /// + /// Creates an instance of the with an asynchronous callback. + /// + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public DialogCloseCallback(Func callback) + { + _callback = callback; + } + + /// + /// Invokes the initialized delegate with no . + /// + public void Invoke() => + Invoke(new DialogResult()); + + /// + /// Invokes the initialized delegate with the specified . + /// + /// The . + /// The . + public void Invoke(IDialogParameters parameters, ButtonResult result = ButtonResult.None) => + Invoke(new DialogResult + { + Parameters = parameters, + Result = result + }); + + /// + /// Invokes the initialized delegate with the specified + /// + /// + public async void Invoke(IDialogResult result) + { + switch(_callback) + { + case Action actionCallback: + actionCallback(result); + break; + case Func taskCallback: + await taskCallback(result); + break; + default: + throw new InvalidOperationException("The DialogCloseCallback has not been properly initialized. This must be initialized by the DialogService, and should not be set by user code."); + } + } +} diff --git a/src/Prism.Core/Dialogs/DialogCloseEvent.cs b/src/Prism.Core/Dialogs/DialogCloseEvent.cs deleted file mode 100644 index 83d09c3474dd0578776ee2825847c83f2e4abdad..0000000000000000000000000000000000000000 --- a/src/Prism.Core/Dialogs/DialogCloseEvent.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.ComponentModel; -using System.Threading.Tasks; - -#nullable enable -namespace Prism.Dialogs; - -/// -/// Provides a type to manage the invocation of a callback to close the Dialog -/// -public struct DialogCloseEvent -{ - private readonly MulticastDelegate _callback; - - /// - /// Creates a default instance of the - /// - public DialogCloseEvent() - { - _callback = () => { }; - } - - /// - /// Creates an instance of the with an callback. - /// - /// The callback to invoke. - [EditorBrowsable(EditorBrowsableState.Never)] - public DialogCloseEvent(Action callback) - { - _callback = callback; - } - - /// - /// Creates an instance of the with an asynchronous callback. - /// - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public DialogCloseEvent(Func callback) - { - _callback = callback; - } - - /// - /// Invokes the initialized delegate with no . - /// - public void Invoke() => - Invoke(new DialogParameters()); - - /// - /// Invokes the initialized delegate with the specified . - /// - /// The . - public async void Invoke(IDialogParameters parameters) - { - switch(_callback) - { - case Action actionCallback: - actionCallback(parameters); - break; - case Func taskCallback: - await taskCallback(parameters); - break; - } - } -} diff --git a/src/Prism.Core/Dialogs/IDialogAware.cs b/src/Prism.Core/Dialogs/IDialogAware.cs index f0a0d92ed93117bf2787773bdaf8b96b9964324a..74503d4406691329d98cfb429daf8b1969b697e6 100644 --- a/src/Prism.Core/Dialogs/IDialogAware.cs +++ b/src/Prism.Core/Dialogs/IDialogAware.cs @@ -23,8 +23,8 @@ public interface IDialogAware void OnDialogOpened(IDialogParameters parameters); /// - /// The will be set by the and can be called to + /// The will be set by the and can be called to /// invoke the close of the Dialog. /// - DialogCloseEvent RequestClose { get; set; } + DialogCloseCallback RequestClose { get; set; } } diff --git a/src/Uno/Prism.Uno/Dialogs/DialogService.cs b/src/Uno/Prism.Uno/Dialogs/DialogService.cs index fa1c13017ba8a5cd8c09d253dcdebc2663263b26..ea1fe9163aedf8f5a2f5a2a74a9476d1bd78d12a 100644 --- a/src/Uno/Prism.Uno/Dialogs/DialogService.cs +++ b/src/Uno/Prism.Uno/Dialogs/DialogService.cs @@ -58,10 +58,9 @@ namespace Prism.Dialogs { IDialogResult result = null; - Action requestCloseHandler = null; - requestCloseHandler = (p) => + Action requestCloseHandler = (r) => { - result = new DialogResult { Parameters = p }; + result = r ?? new DialogResult(); contentDialog.Hide(); }; @@ -72,7 +71,7 @@ namespace Prism.Dialogs if (contentDialog.DataContext is IDialogAware dialogAware) { - dialogAware.RequestClose = new DialogCloseEvent(requestCloseHandler); + dialogAware.RequestClose = new DialogCloseCallback(requestCloseHandler); } }; diff --git a/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs b/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs index 62e9522f7b7638783b419d0a4d951bdf24b8fba1..a62574b75891f7e76dabbf460485e1274e2b0361 100644 --- a/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs +++ b/src/Wpf/Prism.Wpf/Dialogs/DialogService.cs @@ -100,10 +100,9 @@ namespace Prism.Dialogs /// The action to perform when the dialog is closed. protected virtual void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, DialogCallback callback) { - Action requestCloseHandler = null; - requestCloseHandler = (p) => + Action requestCloseHandler = (r) => { - dialogWindow.Result = new DialogResult { Parameters = p }; + dialogWindow.Result = r; dialogWindow.Close(); }; @@ -111,7 +110,7 @@ namespace Prism.Dialogs loadedHandler = (o, e) => { dialogWindow.Loaded -= loadedHandler; - dialogWindow.GetDialogViewModel().RequestClose = new DialogCloseEvent(requestCloseHandler); + dialogWindow.GetDialogViewModel().RequestClose = new DialogCloseCallback(requestCloseHandler); }; dialogWindow.Loaded += loadedHandler; diff --git a/tests/Forms/Prism.Forms.Tests/Services/Mocks/Dialogs/DialogMockViewModel.cs b/tests/Forms/Prism.Forms.Tests/Services/Mocks/Dialogs/DialogMockViewModel.cs index c0fcbf9ea4d283070099f88582f025d92fc92454..0146bf0ab21024329473aab5b8cdd84a645e6055 100644 --- a/tests/Forms/Prism.Forms.Tests/Services/Mocks/Dialogs/DialogMockViewModel.cs +++ b/tests/Forms/Prism.Forms.Tests/Services/Mocks/Dialogs/DialogMockViewModel.cs @@ -1,7 +1,5 @@ -using System; -using Prism.AppModel; +using Prism.Dialogs; using Prism.Mvvm; -using Prism.Dialogs; namespace Prism.Forms.Tests.Services.Mocks.Dialogs { @@ -14,7 +12,7 @@ namespace Prism.Forms.Tests.Services.Mocks.Dialogs set => SetProperty(ref _title, value); } - public DialogCloseEvent RequestClose { get; set; } + public DialogCloseCallback RequestClose { get; set; } public bool CanClose { get; set; } = true;