From 683c4477e0efa3d9289ecbaff3a580a7552cfbd3 Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Thu, 31 Oct 2024 10:39:58 -0300 Subject: [PATCH 1/8] feat: Included setting "ChangeFocusOnUsernameFieldWithEnter" in LoginDialogSettings to change focus from the username field to the password field when pressing ENTER on the username field --- .../Controls/Dialogs/LoginDialog.xaml.cs | 165 ++++++++++-------- .../Controls/Dialogs/LoginDialogSettings.cs | 2 + 2 files changed, 95 insertions(+), 72 deletions(-) diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs index 2cc3320c36..a5a72c51b4 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.xaml.cs @@ -21,7 +21,7 @@ public partial class LoginDialog : BaseMetroDialog public string Message { - get { return (string)this.GetValue(MessageProperty); } + get { return (string) this.GetValue(MessageProperty); } set { this.SetValue(MessageProperty, value); } } @@ -30,7 +30,7 @@ public string Message public string Username { - get { return (string)this.GetValue(UsernameProperty); } + get { return (string) this.GetValue(UsernameProperty); } set { this.SetValue(UsernameProperty, value); } } @@ -39,7 +39,7 @@ public string Username public string UsernameWatermark { - get { return (string)this.GetValue(UsernameWatermarkProperty); } + get { return (string) this.GetValue(UsernameWatermarkProperty); } set { this.SetValue(UsernameWatermarkProperty, value); } } @@ -48,7 +48,7 @@ public string UsernameWatermark public CharacterCasing UsernameCharacterCasing { - get { return (CharacterCasing)this.GetValue(UsernameCharacterCasingProperty); } + get { return (CharacterCasing) this.GetValue(UsernameCharacterCasingProperty); } set { this.SetValue(UsernameCharacterCasingProperty, value); } } @@ -57,7 +57,7 @@ public CharacterCasing UsernameCharacterCasing public string Password { - get { return (string)this.GetValue(PasswordProperty); } + get { return (string) this.GetValue(PasswordProperty); } set { this.SetValue(PasswordProperty, value); } } @@ -66,7 +66,7 @@ public string Password public string PasswordWatermark { - get { return (string)this.GetValue(PasswordWatermarkProperty); } + get { return (string) this.GetValue(PasswordWatermarkProperty); } set { this.SetValue(PasswordWatermarkProperty, value); } } @@ -75,7 +75,7 @@ public string PasswordWatermark public string AffirmativeButtonText { - get { return (string)this.GetValue(AffirmativeButtonTextProperty); } + get { return (string) this.GetValue(AffirmativeButtonTextProperty); } set { this.SetValue(AffirmativeButtonTextProperty, value); } } @@ -84,7 +84,7 @@ public string AffirmativeButtonText public string NegativeButtonText { - get { return (string)this.GetValue(NegativeButtonTextProperty); } + get { return (string) this.GetValue(NegativeButtonTextProperty); } set { this.SetValue(NegativeButtonTextProperty, value); } } @@ -93,7 +93,7 @@ public string NegativeButtonText public Visibility NegativeButtonButtonVisibility { - get { return (Visibility)this.GetValue(NegativeButtonButtonVisibilityProperty); } + get { return (Visibility) this.GetValue(NegativeButtonButtonVisibilityProperty); } set { this.SetValue(NegativeButtonButtonVisibilityProperty, value); } } @@ -102,7 +102,7 @@ public Visibility NegativeButtonButtonVisibility public bool ShouldHideUsername { - get { return (bool)this.GetValue(ShouldHideUsernameProperty); } + get { return (bool) this.GetValue(ShouldHideUsernameProperty); } set { this.SetValue(ShouldHideUsernameProperty, BooleanBoxes.Box(value)); } } @@ -111,7 +111,7 @@ public bool ShouldHideUsername public Visibility RememberCheckBoxVisibility { - get { return (Visibility)this.GetValue(RememberCheckBoxVisibilityProperty); } + get { return (Visibility) this.GetValue(RememberCheckBoxVisibilityProperty); } set { this.SetValue(RememberCheckBoxVisibilityProperty, value); } } @@ -120,7 +120,7 @@ public Visibility RememberCheckBoxVisibility public string RememberCheckBoxText { - get { return (string)this.GetValue(RememberCheckBoxTextProperty); } + get { return (string) this.GetValue(RememberCheckBoxTextProperty); } set { this.SetValue(RememberCheckBoxTextProperty, value); } } @@ -129,10 +129,23 @@ public string RememberCheckBoxText public bool RememberCheckBoxChecked { - get { return (bool)this.GetValue(RememberCheckBoxCheckedProperty); } + get { return (bool) this.GetValue(RememberCheckBoxCheckedProperty); } set { this.SetValue(RememberCheckBoxCheckedProperty, BooleanBoxes.Box(value)); } } + /// Identifies the dependency property. + public static readonly DependencyProperty ChangeFocusWithEnterOnUsernameFieldProperty + = DependencyProperty.Register(nameof(ChangeFocusWithEnterOnUsernameField), + typeof(bool), + typeof(LoginDialog), + new PropertyMetadata(default(bool))); + + public bool ChangeFocusWithEnterOnUsernameField + { + get => (bool) this.GetValue(ChangeFocusWithEnterOnUsernameFieldProperty); + set => this.SetValue(ChangeFocusWithEnterOnUsernameFieldProperty, value); + } + internal LoginDialog() : this(null) { @@ -157,22 +170,23 @@ internal LoginDialog(MetroWindow parentWindow, LoginDialogSettings settings) this.RememberCheckBoxVisibility = settings.RememberCheckBoxVisibility; this.RememberCheckBoxText = settings.RememberCheckBoxText; this.RememberCheckBoxChecked = settings.RememberCheckBoxChecked; + this.ChangeFocusWithEnterOnUsernameField = settings.ChangeFocusOnUsernameFieldWithEnter; } internal Task WaitForButtonPressAsync() { this.Dispatcher.BeginInvoke(new Action(() => + { + this.Focus(); + if (string.IsNullOrEmpty(this.PART_TextBox.Text) && !this.ShouldHideUsername) { - this.Focus(); - if (string.IsNullOrEmpty(this.PART_TextBox.Text) && !this.ShouldHideUsername) - { - this.PART_TextBox.Focus(); - } - else - { - this.PART_TextBox2.Focus(); - } - })); + this.PART_TextBox.Focus(); + } + else + { + this.PART_TextBox2.Focus(); + } + })); TaskCompletionSource tcs = new TaskCompletionSource(); @@ -185,88 +199,95 @@ internal Task WaitForButtonPressAsync() KeyEventHandler escapeKeyHandler = null; Action cleanUpHandlers = () => - { - this.PART_TextBox.KeyDown -= affirmativeKeyHandler; - this.PART_TextBox2.KeyDown -= affirmativeKeyHandler; + { + this.PART_TextBox.KeyDown -= affirmativeKeyHandler; + this.PART_TextBox2.KeyDown -= affirmativeKeyHandler; - this.KeyDown -= escapeKeyHandler; + this.KeyDown -= escapeKeyHandler; - this.PART_NegativeButton.Click -= negativeHandler; - this.PART_AffirmativeButton.Click -= affirmativeHandler; + this.PART_NegativeButton.Click -= negativeHandler; + this.PART_AffirmativeButton.Click -= affirmativeHandler; - this.PART_NegativeButton.KeyDown -= negativeKeyHandler; - this.PART_AffirmativeButton.KeyDown -= affirmativeKeyHandler; + this.PART_NegativeButton.KeyDown -= negativeKeyHandler; + this.PART_AffirmativeButton.KeyDown -= affirmativeKeyHandler; - this.cancellationTokenRegistration.Dispose(); - }; + this.cancellationTokenRegistration.Dispose(); + }; this.cancellationTokenRegistration = this.DialogSettings .CancellationToken .Register(() => + { + this.BeginInvoke(() => { - this.BeginInvoke(() => - { - cleanUpHandlers(); - tcs.TrySetResult(null); - }); + cleanUpHandlers(); + tcs.TrySetResult(null); }); + }); escapeKeyHandler = (sender, e) => + { + if (e.Key == Key.Escape || (e.Key == Key.System && e.SystemKey == Key.F4)) { - if (e.Key == Key.Escape || (e.Key == Key.System && e.SystemKey == Key.F4)) - { - cleanUpHandlers(); + cleanUpHandlers(); - tcs.TrySetResult(null); - } - }; + tcs.TrySetResult(null); + } + }; negativeKeyHandler = (sender, e) => + { + if (e.Key == Key.Enter) { - if (e.Key == Key.Enter) - { - cleanUpHandlers(); + cleanUpHandlers(); - tcs.TrySetResult(null); - } - }; + tcs.TrySetResult(null); + } + }; affirmativeKeyHandler = (sender, e) => + { + if (e.Key == Key.Enter) { - if (e.Key == Key.Enter) + if (PART_TextBox != null && PART_TextBox.IsFocused && ChangeFocusWithEnterOnUsernameField) + { + PART_TextBox2?.Focus(); + } + else { cleanUpHandlers(); tcs.TrySetResult(new LoginDialogData - { - Username = this.Username, - SecurePassword = this.PART_TextBox2.SecurePassword, - ShouldRemember = this.RememberCheckBoxChecked - }); + { + Username = this.Username, + SecurePassword = this.PART_TextBox2.SecurePassword, + ShouldRemember = this.RememberCheckBoxChecked + }); } - }; + } + }; negativeHandler = (sender, e) => - { - cleanUpHandlers(); + { + cleanUpHandlers(); - tcs.TrySetResult(null); + tcs.TrySetResult(null); - e.Handled = true; - }; + e.Handled = true; + }; affirmativeHandler = (sender, e) => - { - cleanUpHandlers(); + { + cleanUpHandlers(); - tcs.TrySetResult(new LoginDialogData - { - Username = this.Username, - SecurePassword = this.PART_TextBox2.SecurePassword, - ShouldRemember = this.RememberCheckBoxChecked - }); + tcs.TrySetResult(new LoginDialogData + { + Username = this.Username, + SecurePassword = this.PART_TextBox2.SecurePassword, + ShouldRemember = this.RememberCheckBoxChecked + }); - e.Handled = true; - }; + e.Handled = true; + }; this.PART_NegativeButton.KeyDown += negativeKeyHandler; this.PART_AffirmativeButton.KeyDown += affirmativeKeyHandler; diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs index 84ea926421..1f6f700c8b 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs @@ -48,5 +48,7 @@ public LoginDialogSettings() public string RememberCheckBoxText { get; set; } public bool RememberCheckBoxChecked { get; set; } + + public bool ChangeFocusOnUsernameFieldWithEnter { get; set; } = false; } } \ No newline at end of file From b04a162e57e0b610bef23271db31b35dcc21c3ed Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Thu, 31 Oct 2024 11:14:23 -0300 Subject: [PATCH 2/8] feat: Included setting "ChangeFocusOnUsernameFieldWithEnter" in LoginDialogSettings to change focus from the username field to the password field when pressing ENTER on the username field --- .../Controls/Dialogs/LoginDialog.cs | 41 ++++++++++++++----- .../Controls/Dialogs/LoginDialogSettings.cs | 2 + 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs index a44cd2d999..4a2d3e8a6a 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs @@ -224,6 +224,19 @@ public bool RememberCheckBoxChecked set => this.SetValue(RememberCheckBoxCheckedProperty, BooleanBoxes.Box(value)); } + /// Identifies the dependency property. + public static readonly DependencyProperty ChangeFocusWithEnterOnUsernameFieldProperty + = DependencyProperty.Register(nameof(ChangeFocusWithEnterOnUsernameField), + typeof(bool), + typeof(LoginDialog), + new PropertyMetadata(default(bool))); + + public bool ChangeFocusWithEnterOnUsernameField + { + get => (bool) this.GetValue(ChangeFocusWithEnterOnUsernameFieldProperty); + set => this.SetValue(ChangeFocusWithEnterOnUsernameFieldProperty, value); + } + #endregion DependencyProperties #region Constructor @@ -257,6 +270,7 @@ internal LoginDialog(MetroWindow? parentWindow, LoginDialogSettings? settings) this.SetCurrentValue(RememberCheckBoxVisibilityProperty, loginDialogSettings.RememberCheckBoxVisibility); this.SetCurrentValue(RememberCheckBoxTextProperty, loginDialogSettings.RememberCheckBoxText); this.SetCurrentValue(RememberCheckBoxCheckedProperty, loginDialogSettings.RememberCheckBoxChecked); + this.SetCurrentValue(ChangeFocusWithEnterOnUsernameFieldProperty, loginDialogSettings.ChangeFocusWithEnterOnUsernameField); } } @@ -299,16 +313,23 @@ private void OnKeyDownHandler(object sender, KeyEventArgs e) } else if (e.Key == Key.Enter) { - this.CleanUpHandlers(); - - this.tcs.TrySetResult(!ReferenceEquals(sender, this.PART_NegativeButton) - ? new LoginDialogData - { - Username = this.Username, - SecurePassword = this.PART_PasswordBox?.SecurePassword, - ShouldRemember = this.RememberCheckBoxChecked - } - : null!); + if (PART_TextBox != null && PART_TextBox.IsFocused && ChangeFocusWithEnterOnUsernameField) + { + PART_PasswordBox?.Focus(); + } + else + { + this.CleanUpHandlers(); + + this.tcs.TrySetResult(!ReferenceEquals(sender, this.PART_NegativeButton) + ? new LoginDialogData + { + Username = this.Username, + SecurePassword = this.PART_PasswordBox?.SecurePassword, + ShouldRemember = this.RememberCheckBoxChecked + } + : null!); + } e.Handled = true; } diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs index 884e280962..ade86bdf91 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs @@ -61,5 +61,7 @@ public LoginDialogSettings(MetroDialogSettings? source) public string RememberCheckBoxText { get; set; } = DefaultRememberCheckBoxText; public bool RememberCheckBoxChecked { get; set; } = false; + + public bool ChangeFocusWithEnterOnUsernameField { get; set; } = false; } } \ No newline at end of file From 247f75728e199ed0eb17c780406f51c33c5f0623 Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Thu, 31 Oct 2024 11:26:56 -0300 Subject: [PATCH 3/8] fix property names --- .../Controls/Dialogs/LoginDialog.cs | 16 ++++++++-------- .../Controls/Dialogs/LoginDialogSettings.cs | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs index 4a2d3e8a6a..266d71d816 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialog.cs @@ -224,17 +224,17 @@ public bool RememberCheckBoxChecked set => this.SetValue(RememberCheckBoxCheckedProperty, BooleanBoxes.Box(value)); } - /// Identifies the dependency property. - public static readonly DependencyProperty ChangeFocusWithEnterOnUsernameFieldProperty - = DependencyProperty.Register(nameof(ChangeFocusWithEnterOnUsernameField), + /// Identifies the dependency property. + public static readonly DependencyProperty ChangeFocusOnUsernameFieldWithEnterProperty + = DependencyProperty.Register(nameof(ChangeFocusOnUsernameFieldWithEnter), typeof(bool), typeof(LoginDialog), new PropertyMetadata(default(bool))); - public bool ChangeFocusWithEnterOnUsernameField + public bool ChangeFocusOnUsernameFieldWithEnter { - get => (bool) this.GetValue(ChangeFocusWithEnterOnUsernameFieldProperty); - set => this.SetValue(ChangeFocusWithEnterOnUsernameFieldProperty, value); + get => (bool) this.GetValue(ChangeFocusOnUsernameFieldWithEnterProperty); + set => this.SetValue(ChangeFocusOnUsernameFieldWithEnterProperty, value); } #endregion DependencyProperties @@ -270,7 +270,7 @@ internal LoginDialog(MetroWindow? parentWindow, LoginDialogSettings? settings) this.SetCurrentValue(RememberCheckBoxVisibilityProperty, loginDialogSettings.RememberCheckBoxVisibility); this.SetCurrentValue(RememberCheckBoxTextProperty, loginDialogSettings.RememberCheckBoxText); this.SetCurrentValue(RememberCheckBoxCheckedProperty, loginDialogSettings.RememberCheckBoxChecked); - this.SetCurrentValue(ChangeFocusWithEnterOnUsernameFieldProperty, loginDialogSettings.ChangeFocusWithEnterOnUsernameField); + this.SetCurrentValue(ChangeFocusOnUsernameFieldWithEnterProperty, loginDialogSettings.ChangeFocusOnUsernameFieldWithEnter); } } @@ -313,7 +313,7 @@ private void OnKeyDownHandler(object sender, KeyEventArgs e) } else if (e.Key == Key.Enter) { - if (PART_TextBox != null && PART_TextBox.IsFocused && ChangeFocusWithEnterOnUsernameField) + if (PART_TextBox != null && PART_TextBox.IsFocused && ChangeFocusOnUsernameFieldWithEnter) { PART_PasswordBox?.Focus(); } diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs index ade86bdf91..f8625f1a1a 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs @@ -62,6 +62,6 @@ public LoginDialogSettings(MetroDialogSettings? source) public bool RememberCheckBoxChecked { get; set; } = false; - public bool ChangeFocusWithEnterOnUsernameField { get; set; } = false; + public bool ChangeFocusOnUsernameFieldWithEnter { get; set; } = false; } } \ No newline at end of file From f9059ba4cf3d3626613549b9c7575b65805a9ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Batista?= Date: Thu, 31 Oct 2024 20:49:04 -0300 Subject: [PATCH 4/8] Remove the initialization to the 'ChangeFocusOnUsernameFieldWithEnter' property --- src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs index f8625f1a1a..900f85ab94 100644 --- a/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs +++ b/src/MahApps.Metro/Controls/Dialogs/LoginDialogSettings.cs @@ -62,6 +62,6 @@ public LoginDialogSettings(MetroDialogSettings? source) public bool RememberCheckBoxChecked { get; set; } = false; - public bool ChangeFocusOnUsernameFieldWithEnter { get; set; } = false; + public bool ChangeFocusOnUsernameFieldWithEnter { get; set; } } } \ No newline at end of file From ca93d26b9623eb24b20e59b99c4afe249c284415 Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Mon, 29 Jun 2026 16:35:53 -0300 Subject: [PATCH 5/8] feat(NumericUpDown): add SyncTextWithValueWhileEditing to refresh text on external value change --- src/MahApps.Metro/Controls/NumericUpDown.cs | 31 +++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/MahApps.Metro/Controls/NumericUpDown.cs b/src/MahApps.Metro/Controls/NumericUpDown.cs index 522b5b963c..55afa31e54 100644 --- a/src/MahApps.Metro/Controls/NumericUpDown.cs +++ b/src/MahApps.Metro/Controls/NumericUpDown.cs @@ -359,6 +359,28 @@ public bool InterceptManualEnter set => this.SetValue(InterceptManualEnterProperty, BooleanBoxes.Box(value)); } + /// Identifies the dependency property. + public static readonly DependencyProperty SyncTextWithValueWhileEditingProperty + = DependencyProperty.Register(nameof(SyncTextWithValueWhileEditing), + typeof(bool), + typeof(NumericUpDown), + new PropertyMetadata(BooleanBoxes.FalseBox)); + + /// + /// Gets or sets a value indicating whether the displayed text is kept in sync with the + /// while the control is being edited (has keyboard focus), when the value + /// is changed from an external source such as a binding. When set to + /// (the default), the current behavior is kept: the text is only refreshed from the value once + /// the control loses focus. + /// + [Category("Behavior")] + [DefaultValue(false)] + public bool SyncTextWithValueWhileEditing + { + get => (bool)this.GetValue(SyncTextWithValueWhileEditingProperty); + set => this.SetValue(SyncTextWithValueWhileEditingProperty, BooleanBoxes.Box(value)); + } + /// Identifies the dependency property. public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), @@ -1097,6 +1119,15 @@ protected virtual void OnValueChanged(double? oldValue, double? newValue) this.InternalSetText(newValue); } } + else if (this.SyncTextWithValueWhileEditing && this.valueTextBox != null) + { + var expectedText = newValue.HasValue ? FormattedValueString(newValue.Value, this.StringFormat, this.SpecificCultureInfo) + : null; + if (!string.Equals(this.valueTextBox.Text, expectedText, StringComparison.Ordinal)) + { + this.InternalSetText(newValue); + } + } if (oldValue != newValue) { From e4f2773a1b8e6f7f7f27d3c091dc58c6f9e4d50d Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Mon, 29 Jun 2026 16:52:34 -0300 Subject: [PATCH 6/8] feat(NumericUpDown): select text after external value sync while editing --- src/MahApps.Metro/Controls/NumericUpDown.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/MahApps.Metro/Controls/NumericUpDown.cs b/src/MahApps.Metro/Controls/NumericUpDown.cs index 55afa31e54..eebebc7870 100644 --- a/src/MahApps.Metro/Controls/NumericUpDown.cs +++ b/src/MahApps.Metro/Controls/NumericUpDown.cs @@ -1126,6 +1126,11 @@ protected virtual void OnValueChanged(double? oldValue, double? newValue) if (!string.Equals(this.valueTextBox.Text, expectedText, StringComparison.Ordinal)) { this.InternalSetText(newValue); + + if (this.valueTextBox.IsKeyboardFocused) + { + this.valueTextBox.SelectAll(); + } } } From 397cabbac85c11929fd9c20547b4d622dbd2f270 Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Tue, 7 Jul 2026 17:10:08 -0300 Subject: [PATCH 7/8] fix(NumericUpDown): keep in-progress text while typing when SyncTextWithValueWhileEditing is on --- src/MahApps.Metro/Controls/NumericUpDown.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/MahApps.Metro/Controls/NumericUpDown.cs b/src/MahApps.Metro/Controls/NumericUpDown.cs index eebebc7870..3cc49117a8 100644 --- a/src/MahApps.Metro/Controls/NumericUpDown.cs +++ b/src/MahApps.Metro/Controls/NumericUpDown.cs @@ -1121,12 +1121,14 @@ protected virtual void OnValueChanged(double? oldValue, double? newValue) } else if (this.SyncTextWithValueWhileEditing && this.valueTextBox != null) { - var expectedText = newValue.HasValue ? FormattedValueString(newValue.Value, this.StringFormat, this.SpecificCultureInfo) - : null; - if (!string.Equals(this.valueTextBox.Text, expectedText, StringComparison.Ordinal)) + var textRepresentsValue = newValue.HasValue + && this.ValidateText(this.valueTextBox.Text, out var textValue) + && FormattedValue(textValue, this.StringFormat, this.SpecificCultureInfo) == newValue.Value; + + if (!textRepresentsValue) { this.InternalSetText(newValue); - + if (this.valueTextBox.IsKeyboardFocused) { this.valueTextBox.SelectAll(); From 29912fc7c8fdd6c0a6382a7e6a64e236a31a41b9 Mon Sep 17 00:00:00 2001 From: Vinicius Cunha Date: Thu, 9 Jul 2026 15:02:21 -0300 Subject: [PATCH 8/8] fix(NumericUpDown): use IsCloseTo instead of exact floating point equality when checking if text represents value --- src/MahApps.Metro/Controls/NumericUpDown.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MahApps.Metro/Controls/NumericUpDown.cs b/src/MahApps.Metro/Controls/NumericUpDown.cs index 5fad5e16c9..5272832120 100644 --- a/src/MahApps.Metro/Controls/NumericUpDown.cs +++ b/src/MahApps.Metro/Controls/NumericUpDown.cs @@ -1264,7 +1264,7 @@ protected virtual void OnValueChanged(double? oldValue, double? newValue) { var textRepresentsValue = newValue.HasValue && this.ValidateText(this.valueTextBox.Text, out var textValue) - && FormattedValue(textValue, this.StringFormat, this.SpecificCultureInfo) == newValue.Value; + && FormattedValue(textValue, this.StringFormat, this.SpecificCultureInfo).IsCloseTo(newValue.Value); if (!textRepresentsValue) {