How to suppress validation when nothing is entered

Viewed 8679

I use WPF data binding with entities that implement IDataErrorInfo interface. In general my code looks like this:

Business entity:

public class Person : IDataErrorInfo 
{
  public string Name { get; set;}

  string IDataErrorInfo.this[string columnName]
  {
    if (columnName=="Name" && string.IsNullOrEmpty(Name))
      return "Name is not entered";
    return string.Empty;
  }  
}

Xaml file:

<TextBox Text="{Binding Path=Name, Mode=TwoWay, ValidatesOnDataErrors=true}" />

When user clicks on "Create new person" following code is executed:

DataContext = new Person();

The problem is that when person is just created its name is empty and WPF immediately draws red frame and shows error message. I want it to show error only when name was already edited and focus is lost. Does anybody know the way to do this?

8 Answers

I believe this behavior to also be a good solution. It removes ErrorTemplate on TextBox when needed and also supports multiple "valid" invalid values (you can also improve it by making ValidInputs a dependency property).

public class NotValidateWhenSpecified : Behavior<TextBox>
{
    private ControlTemplate _errorTemplate;

    public string[] ValidInputs { get; set; } = { string.Empty };

    protected override void OnAttached()
    {
        AssociatedObject.TextChanged += HideValiationIfNecessary;

        _errorTemplate = Validation.GetErrorTemplate(AssociatedObject);
        Validation.SetErrorTemplate(AssociatedObject, null);
    }        

    protected override void OnDetaching()
    {
        AssociatedObject.TextChanged -= HideValiationIfNecessary;
    }

    private void HideValiationIfNecessary(object sender, TextChangedEventArgs e)
    {
        if (ValidInputs.Contains(AssociatedObject.Text))
        {                
            if (_errorTemplate != null)
            {
                _errorTemplate = Validation.GetErrorTemplate(AssociatedObject);
                Validation.SetErrorTemplate(AssociatedObject, null);
            }                
        }
        else
        {
            if (Validation.GetErrorTemplate(AssociatedObject) != _errorTemplate)
            {
                Validation.SetErrorTemplate(AssociatedObject, _errorTemplate);
            }                
        }
    }
}
Related