diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt
index 13ff417b2a..35f38ae3e4 100644
--- a/.github/actions/spell-check/expect.txt
+++ b/.github/actions/spell-check/expect.txt
@@ -1709,6 +1709,7 @@ TOPDOWNDIB
TOUCHEVENTF
TOUCHINPUT
TRACEHANDLE
+TResult
tracelogging
tracerpt
trackbar
@@ -1720,6 +1721,7 @@ triaging
trl
trx
tsa
+TSender
TServer
tstoi
TStr
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
index f8dcd542ea..bc89a38364 100644
--- a/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Controls/IconBox.cs
@@ -2,6 +2,7 @@
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using Microsoft.CmdPal.UI.Deferred;
using Microsoft.CmdPal.UI.ViewModels;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
@@ -90,14 +91,14 @@ public partial class IconBox : ContentControl
{
// TODO GH #239 switch back when using the new MD text block
// _ = @this._queue.EnqueueAsync(() =>
- @this._queue.TryEnqueue(new(() =>
+ @this._queue.TryEnqueue(new(async () =>
{
var requestedTheme = @this.ActualTheme;
var eventArgs = new SourceRequestedEventArgs(e.NewValue, requestedTheme);
if (@this.SourceRequested != null)
{
- @this.SourceRequested.Invoke(@this, eventArgs);
+ await @this.SourceRequested.InvokeAsync(@this, eventArgs);
@this.Source = eventArgs.Value;
@@ -131,7 +132,7 @@ public partial class IconBox : ContentControl
// The range of MDL2 Icons isn't explicitly defined, but
// we're using this based off the table on:
// https://docs.microsoft.com/en-us/windows/uwp/design/style/segoe-ui-symbol-font
- var isMDL2Icon = ch >= '\uE700' && ch <= '\uF8FF';
+ var isMDL2Icon = ch is >= '\uE700' and <= '\uF8FF';
if (!isMDL2Icon)
{
@this.Padding = new Thickness(-4);
diff --git a/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/TypedEventHandlerExtensions.cs b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/TypedEventHandlerExtensions.cs
new file mode 100644
index 0000000000..561ad4592d
--- /dev/null
+++ b/src/modules/cmdpal/Microsoft.CmdPal.UI/Helpers/TypedEventHandlerExtensions.cs
@@ -0,0 +1,72 @@
+// Copyright (c) Microsoft Corporation
+// The Microsoft Corporation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using CommunityToolkit.Common.Deferred;
+using Windows.Foundation;
+
+// Pilfered from CommunityToolkit.WinUI.Deferred
+namespace Microsoft.CmdPal.UI.Deferred;
+
+///
+/// Extensions to for Deferred Events.
+///
+public static class TypedEventHandlerExtensions
+{
+ ///
+ /// Use to invoke an async using .
+ ///
+ /// Type of sender.
+ /// type.
+ /// to be invoked.
+ /// Sender of the event.
+ /// instance.
+ /// to wait on deferred event handler.
+#pragma warning disable CA1715 // Identifiers should have correct prefix
+#pragma warning disable SA1314 // Type parameter names should begin with T
+ public static Task InvokeAsync(this TypedEventHandler eventHandler, S sender, R eventArgs)
+#pragma warning restore SA1314 // Type parameter names should begin with T
+#pragma warning restore CA1715 // Identifiers should have correct prefix
+ where R : DeferredEventArgs => InvokeAsync(eventHandler, sender, eventArgs, CancellationToken.None);
+
+ ///
+ /// Use to invoke an async using with a .
+ ///
+ /// Type of sender.
+ /// type.
+ /// to be invoked.
+ /// Sender of the event.
+ /// instance.
+ /// option.
+ /// to wait on deferred event handler.
+#pragma warning disable CA1715 // Identifiers should have correct prefix
+#pragma warning disable SA1314 // Type parameter names should begin with T
+ public static Task InvokeAsync(this TypedEventHandler eventHandler, S sender, R eventArgs, CancellationToken cancellationToken)
+#pragma warning restore SA1314 // Type parameter names should begin with T
+#pragma warning restore CA1715 // Identifiers should have correct prefix
+ where R : DeferredEventArgs
+ {
+ if (eventHandler == null)
+ {
+ return Task.CompletedTask;
+ }
+
+ var tasks = eventHandler.GetInvocationList()
+ .OfType>()
+ .Select(invocationDelegate =>
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ invocationDelegate(sender, eventArgs);
+
+#pragma warning disable CS0618 // Type or member is obsolete
+ var deferral = eventArgs.GetCurrentDeferralAndReset();
+
+ return deferral?.WaitForCompletion(cancellationToken) ?? Task.CompletedTask;
+#pragma warning restore CS0618 // Type or member is obsolete
+ })
+ .ToArray();
+
+ return Task.WhenAll(tasks);
+ }
+}