ConditionRacer
ConditionRacer

Reputation: 4498

IDataErrorInfo validate before binding occurs

I want to do some simple textbox validation in WPF, but I just realized that IDataErrorInfo relies on raising the PropertyChanged event in order to trigger the validation, which means that the invalid value is applied to my bound object before validation occurs. Is there a way to change this so the validation happens first (and prevents binding on invalid data), or is there another solution that works this way?

Trimmed down code looks like this:

<TextBox>
    <TextBox.Text>
        <Binding Path="MyProperty" ValidatesOnDataErrors="True" />
    </TextBox.Text>
</TextBox>

public class MyViewModel : IDataErrorInfo
{
    public string MyProperty
    {
        get { return _myProperty; }
        set
        {
            if (_myProperty != value)
            {
                _myProperty = value;
                NotifyPropertyChanged(() => MyProperty);
                SaveSettings();
            }
        }
    }

    public string Error
    {
        get { return string.Empty; }
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName == "MyProperty")
                return "ERROR";
            return string.Empty;
        }
    }
}

Upvotes: 1

Views: 597

Answers (2)

Andrew Hanlon
Andrew Hanlon

Reputation: 7421

The better interface and validation method to use (if using .net 4.5) is INotifyDataErrorInfo. It's main advantage is allowing you to control when and how the validation occurs. One good overview:

http://anthymecaillard.wordpress.com/2012/03/26/wpf-4-5-validation-asynchrone/

Upvotes: 1

Vlad Bezden
Vlad Bezden

Reputation: 89517

I don't think you need to call SaveSettings() method every time property changed. I think it should be called when user click on "Save" button, but not when property changed. However if you still would like to save changes on property changed, you should only do it if there are no validation errors available. For instance:

public class MyViewModel : IDataErrorInfo
{
    public string MyProperty
    {
        get { return _myProperty; }
        set
        {
            if (_myProperty != value)
            {
                _myProperty = value;
                NotifyPropertyChanged(() => MyProperty);
                if (string.IsNullOrEmpty(this["MyProperty"]))
                {
                    SaveSettings();
                }
            }
        }
    }

    public string Error
    {
        get { return string.Empty; }
    }

    public string this[string columnName]
    {
        get
        {
            if (columnName == "MyProperty")
                return "ERROR";
            return string.Empty;
        }
    }
}

Upvotes: 0

Related Questions