Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3215] NumericUpDown - Hexdecimal input mode #3256

Conversation

Stephen-Ross
Copy link

I have removed the handling for non-digits within the preview text input and this is now deferred until we attempt to parse the text value into the numeric representation.

The user is now able to specify their own parsing number style instead of replying on NumberStyles.Any. This means that we can correctly parse the value based on what the user wants, this also means that we will parse the value as an integer if the user supplies an input mode of 'Number'. The default of this value is NumerStyles.Any so as to maintain backwards compatibility.

I've manually tested this with as many use cases and data as I could think of and the existing behaviour of the NumericUpDown appears to have been maintained.

There does not appear to be any unit tests covering the NumericUpDown so I was unable to validate against any expect behaviour that I may have manually missed.

…e user to specify the parsing number style.
@punker76
Copy link
Member

punker76 commented Jun 7, 2018

@Stephen-Ross thx for contributing with this feature. I changed your initial thought of separate checking decimal and numeric input, cause your changes doesn't works. A hexadecimal input can not be converted with double. The other change was, that the user now could type any character in, which was not allowed befoire your PR.

I think the current one is now nearly the same as before including your new property which allows now hexadicaml input. I will make some tests after this PR. thx

@sensitron
Copy link

sensitron commented Jul 31, 2018

@Stephen-Ross, @punker76 : When changing the StringFormat with a Trigger it will change the NumericInputeMode to all:

    private static void OnStringFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        NumericUpDown nud = (NumericUpDown)d;

        if (nud._valueTextBox != null && nud.Value.HasValue)
        {
            nud.InternalSetText(nud.Value);
        }

        var value = (string)e.NewValue;

        if (!nud.NumericInputMode.HasFlag(NumericInput.Decimal) && !string.IsNullOrEmpty(value) && RegexStringFormatHexadecimal.IsMatch(value))
        {
            nud.SetCurrentValue(NumericInputModeProperty, nud.NumericInputMode | NumericInput.Decimal);
        }
    }

Which will result in an Exception when typing a hexadecimal value into the TextBox.

    private bool ValidateText(string text, out double convertedValue)
    {
        // If we are only accepting numbers then attempt to parse as an integer.
        if (NumericInputMode == NumericInput.Numbers)
        {
            return ConvertNumber(text, out convertedValue);
        }

        if (!double.TryParse(text, ParsingNumberStyle, SpecificCultureInfo, out convertedValue))
        { ......

=> System.ArgumentException, because AllowHexSpecifier can't be parsed.

My current workaround:

Also set the NumericInputeMode to Numbers in the Trigger:

                    <controls:NumericUpDown.Style>
                        <Style TargetType="controls:NumericUpDown" BasedOn="{StaticResource {x:Type controls:NumericUpDown}}">
                            <Setter Property="NumericInputMode" Value="Numbers"></Setter>
                            <Setter Property="ParsingNumberStyle" Value="Any"></Setter>
                            <Setter Property="StringFormat" Value=""></Setter>
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding ElementName=HexaCheckBox, Path=IsChecked}" Value="True">
                                    <Setter Property="ParsingNumberStyle" Value="AllowHexSpecifier"></Setter>
                                    <Setter Property="StringFormat" Value="{}{0:X0}"></Setter>

                                    <Setter Property="NumericInputMode" Value="Numbers"></Setter>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </controls:NumericUpDown.Style>

The alternative is adding a "&& nud.ParsingNumberStyle != NumberStyles.AllowHexSpecifier" in the OnFormatStringChanged-Method, which also works for me:

    private static void OnStringFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        NumericUpDown nud = (NumericUpDown)d;

        if (nud._valueTextBox != null && nud.Value.HasValue)
        {
            nud.InternalSetText(nud.Value);
        }

        var value = (string)e.NewValue;

        if (!nud.NumericInputMode.HasFlag(NumericInput.Decimal) && !string.IsNullOrEmpty(value) && RegexStringFormatHexadecimal.IsMatch(value) && nud.ParsingNumberStyle != NumberStyles.AllowHexSpecifier)
        {
            nud.SetCurrentValue(NumericInputModeProperty, nud.NumericInputMode | NumericInput.Decimal);
        }
    }

@sensitron
Copy link

Oh nevermind @punker76 ... I saw you already fixed that problem in #3268, sorry :P

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

3 participants