Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Validation in WPF - Various WPF Validation Ways

0.00/5 (No votes)
15 Mar 2017 1  
Adding Validation to controls in WPF

Introduction

In this article, we will see how validation can be done in WPF and also how the error can be displayed.

There are 3 ways in which the validation can be done in WPF.

  1. By using Exception validation
  2. By using IDataErrorInfo
  3. By using ValidationRules

Using the Code

The example is very simple, we will add validation to the name property such that the characters of name is >6 and <10.

The View

So we will start implementing error validation by using each of the ways defined earlier.

By Using Exception Validation

In this way of validation, it is important that we specify ValidatesOnExceptions=True on the binding. Here, the framework will check for any exception thrown when the setter of the associated binding property is called. The framework will catch the exception ArgumentException and marks the field with error state.

The View
<TextBox Text="{Binding StudentName, 
                ValidatesOnExceptions=True,
                UpdateSourceTrigger=PropertyChanged}" 
                VerticalAlignment="Center" 
                FontSize="20"/> 
The Code behind View
namespace TestWpfValidation
{
    public partial class MainWindow : Window
    {
        private string _studentName;

        public string StudentName
        {
            get { return _studentName; }
            set
            {
                if (value.Length < 6 || value.Length > 50)
                {
                    throw new ArgumentException("Name should be between range 6-50");
                }

                _studentName = value;
            }
        }

        public MainWindow()
        {
            this.DataContext = this;
            InitializeComponent();
        }
    }
}

Output

So after running this application you observe that the textbox validates itself, but it does not display error message in a beautiful manner. We will tackle how to display the error message at the end using styles.

Key Notes to Implement

  1. In the setter, the binded property setter needs to throw ArgumentException with error message as parameter to this exception.
  2. In View, make ValidatesOnExceptions=True on the property.

By Using IDataErrorInfo

The View
TextBox Text="{Binding StudentName, 
               UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" 
               VerticalAlignment="Center" 
               FontSize="20"/>

 

The ViewModel
public partial class MainWindow : Window, IDataErrorInfo, INotifyPropertyChanged
    {
        public MainWindow()
        {
            this.DataContext = this;
            InitializeComponent();
        }

        public string StudentName
        {
            get { return _studentName; }
            set
            {
                _studentName = value;
                OnPropertyChanged("StudentName");
            }
        }

        public string this[string columnName]
        {
            get
            {
                string result = String.Empty;
                if (columnName == "StudentName")
                {
                    if (StudentName.Length < 6 || StudentName.Length > 10)
                    {
                        result = "Name should be between range 3-50";
                    }
                }

                return result;
            }
        }

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

        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }

        private string _studentName;
}    

The Error property on IDataErrorInfo represents the error on the MainWindow. Hence, we are just returning string.empty as we are not validating MainWindow.

Key Notes to Implement

  1. In View, make ValidatesOnDataErrors =True on the property.
  2. For the ViewModel, implement two interfaces IDataErrorInfo, INotifyPropertyChanged.

By Using ValidationRules

Create a Validation Rule by inheriting ValidationRule class and implement the validation logic.

public class StudentNameValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            string valueToValidate = value as string;
            if (valueToValidate.Length < 6 || valueToValidate.Length > 10)
            {
                return new ValidationResult(false, "Name should be between range 3-50");
            }

            return new ValidationResult(true, null);
        }
}

In XAML, define the Validation rule on the control that we created on the binding.

<TextBox VerticalAlignment="Center" FontSize="20"> 
      <TextBox.Text> 
       <Binding Path="StudentName" UpdateSourceTrigger="PropertyChanged"> 
            <Binding.ValidationRules> 
                 <local:StudentNameValidationRule/> 
            </Binding.ValidationRules> 
       </Binding> 
      </TextBox.Text> 
<TextBox>

Key Notes to Implement

  1. Create a new class that implements
  2. Provide the Validation rule that we created to the ValidationRules property in XAML.

Adding Style to the Error

This can be used with all the validations that are defined above.

Also, we can customize the way in which the error should be displayed. This can be done using the controlTemplate with AdornedElementPlaceHolder.

<Style x:Key="GeneralErrorStyle">
            <Setter Property="Validation.ErrorTemplate">
                <Setter.Value>
                    <ControlTemplate>
                        <DockPanel>
                            <TextBlock DockPanel.Dock="Right"
                                       Foreground="Red"
                                       FontSize="12pt"
                                       Text="Error"
                                       ToolTip="{Binding ElementName=placeholder, 
                                       Path= AdornedElement.(Validation.Errors)[0].ErrorContent}"/>
                            <AdornedElementPlaceholder x:Name="placeholder" />
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

And then, this style can be applied on the control in XAML.

<TextBox Style="{StaticResource GeneralErrorStyle}"
                 Text="{Binding StudentName, 
                        UpdateSourceTrigger=PropertyChanged, 
                        ValidatesOnDataErrors=True}"
                 HorizontalAlignment="Left"
                 Width="300"/>

This is how the error is displayed after applying this style:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here