-
Notifications
You must be signed in to change notification settings - Fork 405
/
PopupExtensions.shared.cs
150 lines (127 loc) · 3.79 KB
/
PopupExtensions.shared.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using System.Runtime.CompilerServices;
using CommunityToolkit.Maui.Core;
using Microsoft.Maui.Controls.Platform;
using Microsoft.Maui.Platform;
namespace CommunityToolkit.Maui.Views;
/// <summary>
/// Extension methods for <see cref="Popup"/>.
/// </summary>
public static partial class PopupExtensions
{
/// <summary>
/// Displays a popup.
/// </summary>
/// <param name="page">The current <see cref="Page"/>.</param>
/// <param name="popup">The <see cref="Popup"/> to display.</param>
public static void ShowPopup<TPopup>(this Page page, TPopup popup) where TPopup : Popup
{
#if WINDOWS
// TODO: This is a workaround for https://github.com/dotnet/maui/issues/12970. Remove this `#if Windows` block when the issue is closed
void handler(object? sender, EventArgs args)
{
page.GetCurrentPage().Loaded -= handler;
CreateAndShowPopup(page, popup);
}
page.GetCurrentPage().Loaded += handler;
#else
if (page.IsPlatformEnabled)
{
CreateAndShowPopup(page, popup);
}
else
{
void handler(object? sender, EventArgs args)
{
page.Loaded -= handler;
CreateAndShowPopup(page, popup);
}
page.Loaded += handler;
}
#endif
}
/// <summary>
/// Displays a popup and returns a result.
/// </summary>
/// <param name="page">The current <see cref="Page"/>.</param>
/// <param name="popup">The <see cref="Popup"/> to display.</param>
/// <param name="token"><see cref="CancellationToken"/></param>
/// <returns>
/// A task that will complete once the <see cref="Popup"/> is dismissed.
/// </returns>
public static Task<object?> ShowPopupAsync<TPopup>(this Page page, TPopup popup, CancellationToken token = default) where TPopup : Popup
{
#if WINDOWS
// TODO: This is a workaround for https://github.com/dotnet/maui/issues/12970. Remove this `#if Windows` block when the issue is closed
var taskCompletionSource = new TaskCompletionSource<object?>();
async void handler(object? sender, EventArgs args)
{
page.GetCurrentPage().Loaded -= handler;
try
{
var result = await CreateAndShowPopupAsync(page, popup, token);
taskCompletionSource.TrySetResult(result);
}
catch (Exception ex)
{
taskCompletionSource.TrySetException(ex);
}
}
page.GetCurrentPage().Loaded += handler;
return taskCompletionSource.Task.WaitAsync(token);
#else
if (page.IsPlatformEnabled)
{
return CreateAndShowPopupAsync(page, popup, token);
}
else
{
var taskCompletionSource = new TaskCompletionSource<object?>();
async void handler(object? sender, EventArgs args)
{
page.Loaded -= handler;
try
{
var result = await CreateAndShowPopupAsync(page, popup, token);
taskCompletionSource.TrySetResult(result);
}
catch (Exception ex)
{
taskCompletionSource.TrySetException(ex);
}
}
page.Loaded += handler;
return taskCompletionSource.Task;
}
#endif
}
static void CreatePopup(Page page, Popup popup)
{
var mauiContext = GetMauiContext(page);
var parent = page.GetCurrentPage();
parent?.AddLogicalChild(popup);
var platformPopup = popup.ToHandler(mauiContext);
platformPopup.Invoke(nameof(IPopup.OnOpened));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
static IMauiContext GetMauiContext(Page page)
{
return page.Handler?.MauiContext ?? throw new InvalidOperationException("Could not locate MauiContext.");
}
static void CreateAndShowPopup<TPopup>(Page page, TPopup popup) where TPopup : Popup
{
#if WINDOWS
PlatformShowPopup(popup, GetMauiContext(page));
#else
CreatePopup(page, popup);
#endif
}
static Task<object?> CreateAndShowPopupAsync<TPopup>(this Page page, TPopup popup, CancellationToken token) where TPopup : Popup
{
#if WINDOWS
return PlatformShowPopupAsync(popup, GetMauiContext(page), token);
#else
CreatePopup(page, popup);
return popup.Result.WaitAsync(token);
#endif
}
}