0

Iv'e got a code that restricts textbox input to numbers, dashes and spaces.It works fine in the window that contains the textbox.

    public static bool IsTextAllowed(string text)
    {
        //regex that matches disallowed text
        Regex regex = new Regex("[^0-9,-]+");
        return !regex.IsMatch(text);
    }

    private void textbox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        e.Handled = !IsTextAllowed(e.Text);
    }

However what I wish to do is put the code into a class so I can access it from multiple windows and pages. That's the part that isn't going so well.

I created a class called 'rules' and copied the bool method into it. I couldn't figure out a way to get the event handler to work in the class though so instead i tried to pass the string value produced by the method to another string, and bind it to 'textbox1'. Here's the code.

public class rules : INotifyPropertyChanged
{

    // String to contain passed on value from the regrex code
    string integers;

    //Method to pass on value to the string 'integers'
    public bool this[string Digits]
    {
        get
        {
            //regex that matches disallowed text
            Regex regex = new Regex("[^0-9,-]+");
            return !regex.IsMatch(integers);
        }
    }

    //Binding
    public string Number
    {
        get
        {
            return integers;
        }
        set
        {
            if (integers != value)
            {
                integers = value;
                RaisePropertyChanged("Number");
            }
        }
    }

    private void RaisePropertyChanged(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged (this, new PropertyChangedEventArgs(prop));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

In the code behind the window I have 'textbox1' in I set the datacontext.

    public signup()
    {
        InitializeComponent();
        Rules = new rules();
        this.DataContext = Rules;
    }

Then I bind 'textbox1' to it in the xaml:

    <TextBox x:Name="textbox1" Text="{Binding Number, Mode=TwoWay, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}" />

Evidently I'm doing something wrong as it accepts any character punched in.

Is there anyway around this?

Offer
  • 630
  • 2
  • 11
  • 28
  • That doesn't actually check against the regex code. It puts the text into `Number` which stores the value in `integers` if it's different. – James May 30 '14 at 10:33
  • Aren't you trying validation rules? http://stackoverflow.com/questions/1268552/how-do-i-get-a-textbox-to-only-accept-numeric-input-in-wpf – Ujjwal May 30 '14 at 10:36
  • I have used IDataErrorInfo for this. It's great because you automatically get the red adorner when the user enters something invalid. – Gayot Fow May 30 '14 at 11:29
  • @James Barrass - Okay, I see your point. Any clue on what to change so that it does? – Offer May 30 '14 at 12:12
  • @Ujjwal - Confirmed. That's where I got it from but I have no clue on how to implement the lower examples. i.e I get errors on "GetValue" and "SetValue". No clue what to make of those so I tried this way. Which leaves me where I started... – Offer May 30 '14 at 12:15
  • @Offer, change the regex validation back to a method and call it within the setter. Note that you'll have to call `RaisePropertyChanged` to update the binding and it won't prevent typing wrong characters in, instead it will check for validity on exit and fail to change/revert the value to it's previous one – James May 30 '14 at 12:20

1 Answers1

1

In the preview you are cancelling the input with the e.Handled

In the setter you are allowing the input
The TextBox still has value - you have done nothing to reset value

This should work
By calling RaisePropertyChanged("Number"); it should reset back if !IsTextAllowed(value)

if (integers == value) return;
if (IsTextAllowed(value)) { integers = value; }
RaisePropertyChanged("Number");
paparazzo
  • 44,497
  • 23
  • 105
  • 176