Prevent invalid textbox input from being bound to business object property?

Go To StackoverFlow.com

2

I have a simple winforms app with one form, a few controls and a business object defined like this:

public class BusinessObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, e);
        }
    }

    private string _phoneNumber;
    public string PhoneNumber
    {
        get { return _phoneNumber; }
        set
        {
            if (_phoneNumber == value)
            {
                return;
            }

            _phoneNumber = value;
            OnPropertyChanged(new PropertyChangedEventArgs("PhoneNumber"));
        }
    }

On my form, I have a textbox that is bound to the PhoneNumber property via a binding source and the data source update mode is set to OnPropertyChanged. This all works as expected. I need to do some validation on the text before it gets assigned to the PhoneNumber property on my business object. I thought that I would do this in the Validating event handler for the textbox and, if the input is invalid, I display my error provider and set e.Cancel = true. Unfortunately, this doesn't prevent the invalid input from being bound to the PhoneNumber property. Is there an easy way to do this?

2012-04-04 18:40
by bmt22033
Since you set the update mode to OnPropertyChanged, it means the data gets pushed to the object on every key stroke. How is your validation logic handling that ? I mean, shouldn't you wait until the user finishes entering the number before validating - Luc Morin 2012-04-05 00:12
You're absolutely right. :-( The textbox is intended for a user to enter an unformatted phone number (by unformatted, I mean only numbers, no + sign, dashes, parens, etc). I'm not currently doing any kind of input filtering in keydown or keypress so they could type ABC and it would accept it. And, as you pointed out, with OnPropertyChanged, that input gets pushed to the object on each keystroke before I can validate it. I'm thinking that I should be using an update mode of OnValidation for this textbox - bmt22033 2012-04-05 13:01


1

As suggested by mrlucmorin, I've changed my update data source mode from "OnPropertyChanged" to "OnValidation" so that the binding only occurs when the textbox loses and gets validated. I did implement validation in the Validating() event handler for my textbox and set e.Cancel = true when the data is invalid. Unfortunately, clicking buttons on my toolbar doesn't seem to cause the textbox to lose focus so the Validating() event never fires but I was able to work around that by calling ValidateChildren() when a toolbar button is clicked. Thanks again to mrlucmorin and ImGreg for the suggestions that ultimately solved my problem!

2012-04-09 13:05
by bmt22033


1

Data Validation might be just the thing you are looking for. Should keep invalid input from changing your objects.

2012-04-04 19:21
by shriek
Thanks shriek. I ran across that via a Google search earlier but it looks like that applies to WPF - bmt22033 2012-04-04 19:37
meh, silly me, didn't see you're using winforms. won't really work - shriek 2012-04-04 20:24
See my edit @user685869 - ImGreg 2012-04-04 21:27


0

According to the msdn, the event you are using is occurring after the value has changed. One option is to store a backup of the data and restore the value that changed. However, this is not an ideal approach.

I would change the how you are validating the controls.

I'm not certain when to do this as it depends on how your code works. Maybe perform your own validation when you lose focus on the textbox control or do the validation when the datasource is to be updated.

EDIT: Perhaps you are looking for the ErrorProvider Class. This can be used to handle validation like you want.

2012-04-04 19:19
by ImGreg
Thanks for the suggestion - bmt22033 2012-04-09 12:59
Ads