...
 
Commits (2)
    https://gitcode.net/jobily/Prism/-/commit/089679d41057d36b51210121ccdf7a0a7f8917e8 chore: enabling nullability checks 2023-07-06T20:24:27-06:00 Dan Siegel me@dansiegel.net https://gitcode.net/jobily/Prism/-/commit/6ec37308c6740a6ab1fb6036b63aa717e0dae8d2 chore: rename to DialogCloseClallback 2023-07-08T21:34:38-06:00 Dan Siegel me@dansiegel.net
......@@ -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<IDialogResult> CloseDialogAsync(IDialogParameters parameters, ContentPage currentPage, DialogPage dialogModal)
private async System.Threading.Tasks.Task<IDialogResult> 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<IActiveAware>(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);
......
......@@ -14,12 +14,19 @@ public sealed class DialogService : IDialogService
private readonly IContainerProvider _container;
private readonly IPageAccessor _pageAccessor;
/// <summary>
/// Creates a new instance of the <see cref="DialogService"/> for Maui Applications
/// </summary>
/// <param name="container">The <see cref="IContainerProvider"/> that will be used to help resolve the Dialog Views.</param>
/// <param name="pageAccessor">The <see cref="IPageAccessor"/> used to determine where in the Navigation Stack we need to process the Dialog.</param>
/// <exception cref="ArgumentNullException">Throws when any constructor arguments are null.</exception>
public DialogService(IContainerProvider container, IPageAccessor pageAccessor)
{
_container = container ?? throw new ArgumentNullException(nameof(container));
_pageAccessor = pageAccessor ?? throw new ArgumentNullException(nameof(pageAccessor));
}
/// <inheritdoc/>
public void ShowDialog(string name, IDialogParameters parameters, DialogCallback callback)
{
try
......@@ -35,11 +42,11 @@ public sealed class DialogService : IDialogService
var dialogModal = _container.Resolve<IDialogContainer>();
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<IDialogResult> CloseDialogAsync(IDialogParameters parameters, Page currentPage, IDialogContainer dialogModal)
private static async Task<IDialogResult> 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<IActiveAware>(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
......
......@@ -2,65 +2,79 @@ using System;
using System.ComponentModel;
using System.Threading.Tasks;
#nullable enable
namespace Prism.Dialogs;
/// <summary>
/// Provides a type to manage the invocation of a callback to close the Dialog
/// This is set by the <see cref="IDialogService"/> on your <see cref="IDialogAware"/> ViewModel. This can then
/// be invoked by either the DialogService or your code to initiate closing the Dialog.
/// </summary>
public struct DialogCloseEvent
public struct DialogCloseCallback
{
private readonly MulticastDelegate _callback;
/// <summary>
/// Creates a default instance of the <see cref="DialogCloseEvent"/>
/// Creates a default instance of the <see cref="DialogCloseCallback"/>
/// </summary>
public DialogCloseEvent()
public DialogCloseCallback()
{
_callback = null;
_callback = () => { };
}
/// <summary>
/// Creates an instance of the <see cref="DialogCloseEvent"/> with an <see cref="Action{IDialogParameters}"/> callback.
/// Creates an instance of the <see cref="DialogCloseCallback"/> with an <see cref="Action{IDialogResult}"/> callback.
/// </summary>
/// <param name="callback">The callback to invoke.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public DialogCloseEvent(Action<IDialogParameters> callback)
public DialogCloseCallback(Action<IDialogResult> callback)
{
_callback = callback;
}
/// <summary>
/// Creates an instance of the <see cref="DialogCloseEvent"/> with an <see cref="Func{IDialogParameters, Task}"/> asynchronous callback.
/// Creates an instance of the <see cref="DialogCloseCallback"/> with an <see cref="Func{IDialogResult, Task}"/> asynchronous callback.
/// </summary>
/// <param name="callback"></param>
[EditorBrowsable(EditorBrowsableState.Never)]
public DialogCloseEvent(Func<IDialogParameters, Task> callback)
public DialogCloseCallback(Func<IDialogResult, Task> callback)
{
_callback = callback;
}
/// <summary>
/// Invokes the initialized delegate with no <see cref="IDialogParameters"/>.
/// Invokes the initialized delegate with no <see cref="IDialogResult"/>.
/// </summary>
public void Invoke() =>
Invoke(null);
Invoke(new DialogResult());
/// <summary>
/// Invokes the initialized delegate with the specified <see cref="IDialogParameters"/>.
/// </summary>
/// <param name="parameters">The <see cref="IDialogParameters"/>.</param>
public async void Invoke(IDialogParameters parameters)
{
parameters ??= new DialogParameters();
/// <param name="result">The <see cref="ButtonResult"/>.</param>
public void Invoke(IDialogParameters parameters, ButtonResult result = ButtonResult.None) =>
Invoke(new DialogResult
{
Parameters = parameters,
Result = result
});
/// <summary>
/// Invokes the initialized delegate with the specified <see cref="IDialogResult"/>
/// </summary>
/// <param name="result"></param>
public async void Invoke(IDialogResult result)
{
switch(_callback)
{
case Action<IDialogParameters> actionCallback:
actionCallback(parameters);
case Action<IDialogResult> actionCallback:
actionCallback(result);
break;
case Func<IDialogParameters, Task> taskCallback:
await taskCallback(parameters);
case Func<IDialogResult, Task> 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.");
}
}
}
......@@ -23,8 +23,8 @@ public interface IDialogAware
void OnDialogOpened(IDialogParameters parameters);
/// <summary>
/// The <see cref="DialogCloseEvent"/> will be set by the <see cref="IDialogService"/> and can be called to
/// The <see cref="DialogCloseCallback"/> will be set by the <see cref="IDialogService"/> and can be called to
/// invoke the close of the Dialog.
/// </summary>
DialogCloseEvent RequestClose { get; set; }
DialogCloseCallback RequestClose { get; set; }
}
......@@ -58,10 +58,9 @@ namespace Prism.Dialogs
{
IDialogResult result = null;
Action<IDialogParameters> requestCloseHandler = null;
requestCloseHandler = (p) =>
Action<IDialogResult> 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);
}
};
......
......@@ -100,10 +100,9 @@ namespace Prism.Dialogs
/// <param name="callback">The action to perform when the dialog is closed.</param>
protected virtual void ConfigureDialogWindowEvents(IDialogWindow dialogWindow, DialogCallback callback)
{
Action<IDialogParameters> requestCloseHandler = null;
requestCloseHandler = (p) =>
Action<IDialogResult> 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;
......
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;
......