0

I'm kind of stuck here.

So what I need is - I have TextBox that can only have the values from -999 to 999. I've tried setting the boundaries like so.

<TextBox Height="{Binding ElementName= SomeComboBox, Path=ActualHeight}"
                                     VerticalAlignment="Top"
                                     Tag="int"
                                     HorizontalAlignment="Stretch"
                                     MaxLength="4"
                                     Margin="2, 4, 0, 0"
                                     AutomationProperties.AutomationId="Something_cbSome">
                                <i:Interaction.Behaviors>
                                    <behaviors:TextBoxIntInputBehavior AllowNegative="True" />
                                </i:Interaction.Behaviors>

                                <TextBox.Text>
                                    <Binding Path="Something"
                                             UpdateSourceTrigger="PropertyChanged"
                                             TargetNullValue="">
                                        <Binding.ValidationRules>
                                            <validation:IntRangeRule Min="-999"
                                                                     Max="999" />
                                        </Binding.ValidationRules>
                                    </Binding>
                                </TextBox.Text>
                            </TextBox>

But the obviously now someone can enter 4 digits since the MaxLength has the value 4. For example 1234 which is higher than the 999.

Also, this allows me to type in things like ---, 8--2 etc.

Desired accepted values : -999 up to 999. No more, no less. How do I do this?

aca
  • 1,071
  • 5
  • 15

3 Answers3

0

The answer is:

  1. You alternatively may use a slider (the another control, it is bad)
  2. Or you can see the ValidationRule class in an another question: ValidationRule for WPF Textbox

Reuse it!

HailToTheVictor
  • 388
  • 2
  • 8
  • 28
  • What you provided, IMO, belongs more to the "comment" section, instead of "answer". Anyways, thanks for the link. – aca Feb 22 '23 at 13:56
  • @aca have a look at what it actually says, then you can decide if it is more of a comment. There is a good advice here and in fact it answers your question. – XAMlMAX Feb 22 '23 at 22:39
0
  <TextBox PreviewTextInput="NumericTextHandler" />

   private void NumericTextHandler(object sender, TextCompositionEventArgs e)
        {
            if (e.Text == "-" && ((TextBox)sender).Text.Length == 0)
            {
                e.Handled = false;
            }
            else if (!int.TryParse(e.Text, out _))
            {
                e.Handled = true;
            }
            else
            {
                var newText = ((TextBox)sender).Text + e.Text;
                if (int.TryParse(newText, out var newValue))
                {
                    e.Handled = newValue is < -999 or > 999;
                }
            }
        }

You could handle The PreviewTextInput event of the Textbox to only accept minus and int as first char. And only values from -999 to 999. This might be an easy alternative that could work for your purpose.

jeb
  • 848
  • 5
  • 16
0

I suggest putting the logic into the view model:

    public class MainViewModel : Binding
    {
        string _MyNumber;
        int _MyValidatedNumber;
        public string MyNumber
        {
            get { return _MyNumber; }
            set
            {
                _MyNumber = value;
                
                if (string.IsNullOrEmpty(_MyNumber))
                {
                    _MyValidatedNumber = 0;
                    _MyNumber = "";
                }
                else if(_MyNumber== "-")
                {
                    _MyValidatedNumber = 0;
                }
                else
                {
                    int temp;
                    if (int.TryParse(_MyNumber, out temp) && (temp <= 999 && temp >= -999))
                    {
                        _MyValidatedNumber = temp;
                    }
                    else
                    {
                        _MyNumber = _MyValidatedNumber.ToString();
                    }
                }
                NotifyPropertyChanged(nameof(MyNumber));
                NotifyPropertyChanged(nameof(MyValidatedNumber));

            }
        }
        public int MyValidatedNumber
        {
            get { return _MyValidatedNumber; }
            set { _MyValidatedNumber = value; NotifyPropertyChanged(nameof(MyValidatedNumber)); }
        }
    }

I use here 2 properties . One for the as-is text and the second one for the validated value.

The XAML code looks as following:

<Grid>
        <Grid.DataContext>
            <local:MainViewModel/>
        </Grid.DataContext>
        <TextBox 
            Text="{Binding MyNumber,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"
                                     VerticalAlignment="Top"
                                     HorizontalAlignment="Stretch"
                                     MaxLength="4"
                                     Margin="2, 4, 0, 0"
                                     AutomationProperties.AutomationId="Something_cbSome"
            ToolTip="{Binding MyValidatedNumber}"
            >
            
        </TextBox>
    </Grid>
Gilad Waisel
  • 120
  • 4