diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 2ddc4a8242..d434c00be0 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1445,6 +1445,7 @@ nuget null nullopt nullptr +numberbox NUMLOCK NUMPAD nunit diff --git a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml index 290961800f..7f8325c22c 100644 --- a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml +++ b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml @@ -398,7 +398,7 @@ Width="72" ui:ControlHelper.CornerRadius="2,0,0,2" AutomationProperties.Name="{x:Static p:Resources.Red_value}" - ValueChanged="RGBNumberBox_ValueChanged" + TextBoxBase.TextChanged="RGBNumberBox_TextChanged" Minimum="0" Maximum="255" /> @@ -408,7 +408,7 @@ Width="72" ui:ControlHelper.CornerRadius="0" AutomationProperties.Name="{x:Static p:Resources.Green_value}" - ValueChanged="RGBNumberBox_ValueChanged" + TextBoxBase.TextChanged="RGBNumberBox_TextChanged" Minimum="0" Maximum="255" /> @@ -418,7 +418,7 @@ Margin="-1,0,0,0" ui:ControlHelper.CornerRadius="0,2,2,0" AutomationProperties.Name="{x:Static p:Resources.Blue_value}" - ValueChanged="RGBNumberBox_ValueChanged" + TextBoxBase.TextChanged="RGBNumberBox_TextChanged" Minimum="0" Maximum="255" /> diff --git a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs index 0ebb473d60..1faac640c5 100644 --- a/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs +++ b/src/modules/colorPicker/ColorPickerUI/Controls/ColorPickerControl.xaml.cs @@ -12,6 +12,7 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using ColorPicker.Helpers; +using ModernWpf.Controls; using ModernWpf.Controls.Primitives; namespace ColorPicker.Controls @@ -297,22 +298,6 @@ namespace ColorPicker.Controls _ignoreGradientsChanges = false; } - private static Point GetMousePositionWithinGrid(Border border) - { - var pos = System.Windows.Input.Mouse.GetPosition(border); - if (pos.X < 0) - { - pos.X = 0; - } - - if (pos.X > border.Width) - { - pos.X = border.Width; - } - - return pos; - } - private void HexCode_TextChanged(object sender, TextChangedEventArgs e) { var newValue = (sender as TextBox).Text; @@ -336,21 +321,6 @@ namespace ColorPicker.Controls } } -#pragma warning disable CA1801 // Review unused parameters - private void RGBNumberBox_ValueChanged(ModernWpf.Controls.NumberBox sender, ModernWpf.Controls.NumberBoxValueChangedEventArgs args) -#pragma warning restore CA1801 // Review unused parameters - { - if (!_ignoreRGBChanges) - { - var r = byte.Parse(RNumberBox.Text, CultureInfo.InvariantCulture); - var g = byte.Parse(GNumberBox.Text, CultureInfo.InvariantCulture); - var b = byte.Parse(BNumberBox.Text, CultureInfo.InvariantCulture); - _ignoreRGBChanges = true; - SetColorFromTextBoxes(System.Drawing.Color.FromArgb(r, g, b)); - _ignoreRGBChanges = false; - } - } - private void SetColorFromTextBoxes(System.Drawing.Color color) { if (!_ignoreGradientsChanges) @@ -377,6 +347,65 @@ namespace ColorPicker.Controls { (sender as System.Windows.Controls.TextBox).SelectAll(); } + + private void RGBNumberBox_TextChanged(object sender, TextChangedEventArgs e) + { + if (!_ignoreRGBChanges) + { + var numberBox = sender as NumberBox; + var r = numberBox.Name == "RNumberBox" ? GetValueFromNumberBox(numberBox) : (byte)RNumberBox.Value; + var g = numberBox.Name == "GNumberBox" ? GetValueFromNumberBox(numberBox) : (byte)GNumberBox.Value; + var b = numberBox.Name == "BNumberBox" ? GetValueFromNumberBox(numberBox) : (byte)BNumberBox.Value; + _ignoreRGBChanges = true; + SetColorFromTextBoxes(System.Drawing.Color.FromArgb(r, g, b)); + _ignoreRGBChanges = false; + } + } + + /// + /// NumberBox provides value only after it has been validated - happens after pressing enter or leaving this control. + /// However, we need to get value immediately after the underlying textbox value changes + /// + /// numberBox control which value we want to get + /// Validated value as per numberbox conditions, if content is invalid it returns previous value + private static byte GetValueFromNumberBox(NumberBox numberBox) + { + var internalTextBox = GetChildOfType(numberBox); + var parsedValue = numberBox.NumberFormatter.ParseDouble(internalTextBox.Text); + if (parsedValue != null) + { + var parsedValueByte = (byte)parsedValue; + if (parsedValueByte >= numberBox.Minimum && parsedValueByte <= numberBox.Maximum) + { + return parsedValueByte; + } + } + + // not valid input, return previous value + return (byte)numberBox.Value; + } + + public static T GetChildOfType(DependencyObject depObj) + where T : DependencyObject + { + if (depObj == null) + { + return null; + } + + for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) + { + var child = VisualTreeHelper.GetChild(depObj, i); + + var result = (child as T) ?? GetChildOfType(child); + if (result != null) + { + return result; + } + } + + return null; + } } #pragma warning disable SA1402 // File may only contain a single type