From 713f916f42297a65a113be67df7c92b5e267ace7 Mon Sep 17 00:00:00 2001 From: punker76 Date: Fri, 4 Dec 2020 22:07:21 +0100 Subject: [PATCH] (GH-3214) Fix InvalidOperationException at registered CancellationToken delegate --- .../Controls/Dialogs/InputDialog.xaml.cs | 26 +++++++++++------- .../Controls/Dialogs/LoginDialog.xaml.cs | 26 +++++++++++------- .../Controls/Dialogs/MessageDialog.xaml.cs | 27 +++++++++++-------- .../Dialogs/ProgressDialogController.cs | 17 ++++++------ 4 files changed, 57 insertions(+), 39 deletions(-) diff --git a/src/MahApps.Metro/Controls/Dialogs/InputDialog.xaml.cs b/src/MahApps.Metro/Controls/Dialogs/InputDialog.xaml.cs index fc2f7eb386..fa43fa3b47 100644 --- a/src/MahApps.Metro/Controls/Dialogs/InputDialog.xaml.cs +++ b/src/MahApps.Metro/Controls/Dialogs/InputDialog.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; @@ -11,6 +12,8 @@ namespace MahApps.Metro.Controls.Dialogs { public partial class InputDialog : BaseMetroDialog { + private CancellationTokenRegistration cancellationTokenRegistration; + /// Identifies the dependency property. public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(InputDialog), new PropertyMetadata(default(string))); @@ -81,15 +84,7 @@ internal Task WaitForButtonPressAsync() KeyEventHandler escapeKeyHandler = null; - Action cleanUpHandlers = null; - - var cancellationTokenRegistration = this.DialogSettings.CancellationToken.Register(() => - { - cleanUpHandlers(); - tcs.TrySetResult(null); - }); - - cleanUpHandlers = () => + Action cleanUpHandlers = () => { this.PART_TextBox.KeyDown -= affirmativeKeyHandler; @@ -101,9 +96,20 @@ internal Task WaitForButtonPressAsync() this.PART_NegativeButton.KeyDown -= negativeKeyHandler; this.PART_AffirmativeButton.KeyDown -= affirmativeKeyHandler; - cancellationTokenRegistration.Dispose(); + this.cancellationTokenRegistration.Dispose(); }; + this.cancellationTokenRegistration = this.DialogSettings + .CancellationToken + .Register(() => + { + this.BeginInvoke(() => + { + cleanUpHandlers(); + tcs.TrySetResult(null); + }); + }); + escapeKeyHandler = (sender, e) => { if (e.Key == Key.Escape || (e.Key == Key.System && e.SystemKey == Key.F4)) diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs index 3d30b4641b..2cc3320c36 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; @@ -13,6 +14,8 @@ namespace MahApps.Metro.Controls.Dialogs { public partial class LoginDialog : BaseMetroDialog { + private CancellationTokenRegistration cancellationTokenRegistration; + /// Identifies the dependency property. public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(LoginDialog), new PropertyMetadata(default(string))); @@ -181,15 +184,7 @@ internal Task WaitForButtonPressAsync() KeyEventHandler escapeKeyHandler = null; - Action cleanUpHandlers = null; - - var cancellationTokenRegistration = this.DialogSettings.CancellationToken.Register(() => - { - cleanUpHandlers(); - tcs.TrySetResult(null); - }); - - cleanUpHandlers = () => + Action cleanUpHandlers = () => { this.PART_TextBox.KeyDown -= affirmativeKeyHandler; this.PART_TextBox2.KeyDown -= affirmativeKeyHandler; @@ -202,9 +197,20 @@ internal Task WaitForButtonPressAsync() this.PART_NegativeButton.KeyDown -= negativeKeyHandler; this.PART_AffirmativeButton.KeyDown -= affirmativeKeyHandler; - cancellationTokenRegistration.Dispose(); + this.cancellationTokenRegistration.Dispose(); }; + this.cancellationTokenRegistration = this.DialogSettings + .CancellationToken + .Register(() => + { + this.BeginInvoke(() => + { + cleanUpHandlers(); + tcs.TrySetResult(null); + }); + }); + escapeKeyHandler = (sender, e) => { if (e.Key == Key.Escape || (e.Key == Key.System && e.SystemKey == Key.F4)) diff --git a/src/MahApps.Metro/Controls/Dialogs/MessageDialog.xaml.cs b/src/MahApps.Metro/Controls/Dialogs/MessageDialog.xaml.cs index 4da6b28621..22d7d04f4f 100644 --- a/src/MahApps.Metro/Controls/Dialogs/MessageDialog.xaml.cs +++ b/src/MahApps.Metro/Controls/Dialogs/MessageDialog.xaml.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Input; @@ -17,6 +18,7 @@ public partial class MessageDialog : BaseMetroDialog { private const string ACCENT_BUTTON_STYLE = "MahApps.Styles.Button.Dialogs.Accent"; private const string ACCENT_HIGHLIGHT_BUTTON_STYLE = "MahApps.Styles.Button.Dialogs.AccentHighlight"; + private CancellationTokenRegistration cancellationTokenRegistration; /// Identifies the dependency property. public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(MessageDialog), new PropertyMetadata(default(string))); @@ -136,7 +138,7 @@ internal Task WaitForButtonPressAsync() } })); - TaskCompletionSource tcs = new TaskCompletionSource(); + var tcs = new TaskCompletionSource(); RoutedEventHandler negativeHandler = null; KeyEventHandler negativeKeyHandler = null; @@ -152,15 +154,7 @@ internal Task WaitForButtonPressAsync() KeyEventHandler escapeKeyHandler = null; - Action cleanUpHandlers = null; - - var cancellationTokenRegistration = this.DialogSettings.CancellationToken.Register(() => - { - cleanUpHandlers?.Invoke(); - tcs.TrySetResult(this.ButtonStyle == MessageDialogStyle.Affirmative ? MessageDialogResult.Affirmative : MessageDialogResult.Negative); - }); - - cleanUpHandlers = () => + Action cleanUpHandlers = () => { this.PART_NegativeButton.Click -= negativeHandler; this.PART_AffirmativeButton.Click -= affirmativeHandler; @@ -174,9 +168,20 @@ internal Task WaitForButtonPressAsync() this.KeyDown -= escapeKeyHandler; - cancellationTokenRegistration.Dispose(); + this.cancellationTokenRegistration.Dispose(); }; + this.cancellationTokenRegistration = this.DialogSettings + .CancellationToken + .Register(() => + { + this.BeginInvoke(() => + { + cleanUpHandlers(); + tcs.TrySetResult(this.ButtonStyle == MessageDialogStyle.Affirmative ? MessageDialogResult.Affirmative : MessageDialogResult.Negative); + }); + }); + negativeKeyHandler = (sender, e) => { if (e.Key == Key.Enter) diff --git a/src/MahApps.Metro/Controls/Dialogs/ProgressDialogController.cs b/src/MahApps.Metro/Controls/Dialogs/ProgressDialogController.cs index 1350231b0b..308bcc2fbd 100644 --- a/src/MahApps.Metro/Controls/Dialogs/ProgressDialogController.cs +++ b/src/MahApps.Metro/Controls/Dialogs/ProgressDialogController.cs @@ -47,18 +47,19 @@ internal ProgressDialogController(ProgressDialog dialog, Func closeCallBac this.WrappedDialog.Invoke(() => { this.WrappedDialog.PART_NegativeButton.Click += this.PART_NegativeButton_Click; }); - dialog.CancellationToken.Register(() => { this.PART_NegativeButton_Click(null, new RoutedEventArgs()); }); + dialog.CancellationToken.Register(() => { this.WrappedDialog.BeginInvoke(this.Abort); }); } private void PART_NegativeButton_Click(object sender, RoutedEventArgs e) { - Action action = () => - { - this.IsCanceled = true; - this.Canceled?.Invoke(this, EventArgs.Empty); - this.WrappedDialog.PART_NegativeButton.IsEnabled = false; - }; - this.WrappedDialog.Invoke(action); + this.WrappedDialog.Invoke(this.Abort); + } + + private void Abort() + { + this.WrappedDialog.PART_NegativeButton.IsEnabled = false; + this.IsCanceled = true; + this.Canceled?.Invoke(this, EventArgs.Empty); } ///