Skip to content

Commit

Permalink
Merge pull request #3993 from MahApps/fix/3214-CancellationToken-Regi…
Browse files Browse the repository at this point in the history
…ster

Fix InvalidOperationException at registered CancellationToken delegate
  • Loading branch information
punker76 authored Dec 4, 2020
2 parents 1d9e6e2 + 713f916 commit dbb4fc2
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 39 deletions.
26 changes: 16 additions & 10 deletions src/MahApps.Metro/Controls/Dialogs/InputDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -11,6 +12,8 @@ namespace MahApps.Metro.Controls.Dialogs
{
public partial class InputDialog : BaseMetroDialog
{
private CancellationTokenRegistration cancellationTokenRegistration;

/// <summary>Identifies the <see cref="Message"/> dependency property.</summary>
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(InputDialog), new PropertyMetadata(default(string)));

Expand Down Expand Up @@ -81,15 +84,7 @@ internal Task<string> 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;
Expand All @@ -101,9 +96,20 @@ internal Task<string> 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))
Expand Down
26 changes: 16 additions & 10 deletions src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -13,6 +14,8 @@ namespace MahApps.Metro.Controls.Dialogs
{
public partial class LoginDialog : BaseMetroDialog
{
private CancellationTokenRegistration cancellationTokenRegistration;

/// <summary>Identifies the <see cref="Message"/> dependency property.</summary>
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(LoginDialog), new PropertyMetadata(default(string)));

Expand Down Expand Up @@ -181,15 +184,7 @@ internal Task<LoginDialogData> 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;
Expand All @@ -202,9 +197,20 @@ internal Task<LoginDialogData> 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))
Expand Down
27 changes: 16 additions & 11 deletions src/MahApps.Metro/Controls/Dialogs/MessageDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

/// <summary>Identifies the <see cref="Message"/> dependency property.</summary>
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register(nameof(Message), typeof(string), typeof(MessageDialog), new PropertyMetadata(default(string)));
Expand Down Expand Up @@ -136,7 +138,7 @@ internal Task<MessageDialogResult> WaitForButtonPressAsync()
}
}));

TaskCompletionSource<MessageDialogResult> tcs = new TaskCompletionSource<MessageDialogResult>();
var tcs = new TaskCompletionSource<MessageDialogResult>();

RoutedEventHandler negativeHandler = null;
KeyEventHandler negativeKeyHandler = null;
Expand All @@ -152,15 +154,7 @@ internal Task<MessageDialogResult> 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;
Expand All @@ -174,9 +168,20 @@ internal Task<MessageDialogResult> 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)
Expand Down
17 changes: 9 additions & 8 deletions src/MahApps.Metro/Controls/Dialogs/ProgressDialogController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,19 @@ internal ProgressDialogController(ProgressDialog dialog, Func<Task> 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);
}

/// <summary>
Expand Down

0 comments on commit dbb4fc2

Please sign in to comment.