1.ValidatesOnExceptions verification
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:system="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="400" Height="500" mc:Ignorable="d"> <Window.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <StackPanel> <TextBox Margin="0,10,0,5" Text="{Binding UserName, ValidatesOnExceptions=True}" /> <TextBox Margin="0,5,0,5" Text="{Binding Age}" /> <Button Content="Reguster" /> </StackPanel> </Window>
using GalaSoft.MvvmLight; using System; namespace WpfApplication { public class MainWindowViewModel : ViewModelBase { private string userName; public string UserName { get { return userName; } set { if (string.IsNullOrWhiteSpace(value) || value.Length < 6 || value.Length > 10) { throw new ArgumentException("Username must be within 6-10 lengths"); } userName = value; RaisePropertyChanged(nameof(UserName)); } } private int age; public int Age { get { return age; } set { age = value; RaisePropertyChanged(nameof(Age)); } } } }
2. Inherit ValidationRule
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:system="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="400" Height="500" mc:Ignorable="d"> <Window.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <StackPanel> <TextBox Margin="0,10,0,5"> <TextBox.Text> <Binding Path="UserName"> <Binding.ValidationRules> <local:StringLengthRule MaxLength="10" MinLength="5" /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Margin="0,5,0,5" Text="{Binding Age}" /> <Button Content="Reguster" /> </StackPanel> </Window>
using GalaSoft.MvvmLight; using System; using System.Globalization; using System.Windows.Controls; namespace WpfApplication { public class MainWindowViewModel : ViewModelBase { private string userName; public string UserName { get { return userName; } set { userName = value; RaisePropertyChanged(nameof(UserName)); } } private int age; public int Age { get { return age; } set { age = value; RaisePropertyChanged(nameof(Age)); } } } public class StringLengthRule : ValidationRule { public int? MinLength { get; set; } public int? MaxLength { get; set; } public override ValidationResult Validate(object value, CultureInfo cultureInfo) { if (!(value is string)) { return new ValidationResult(false, "Value must be a string"); } string ruleValue = value.ToString(); if (string.IsNullOrWhiteSpace(ruleValue)) { return new ValidationResult(false, $"Value must be at least {MinLength} characters long"); } if (MinLength != null & amp; & amp; ruleValue.Length < MinLength) { return new ValidationResult(false, $"Value must be at least {MinLength} characters long"); } if (MaxLength != null & amp; & amp; ruleValue.Length > MaxLength) { return new ValidationResult(false, $"Value must be at least {MaxLength} characters long"); } return ValidationResult.ValidResult; } } }
3. Implement the IDataErrorInfo interface
<Window x:Class="WpfApplication.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:WpfApplication" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:system="clr-namespace:System;assembly=mscorlib" Title="MainWindow" Width="400" Height="500" mc:Ignorable="d"> <Window.Resources> <Style TargetType="TextBox"> <Style.Triggers> <Trigger Property="Validation.HasError" Value="True"> <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" /> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Window.DataContext> <local:MainWindowViewModel /> </Window.DataContext> <StackPanel> <TextBox Margin="0,10,0,5"> <TextBox.Text> <Binding Path="UserName"> <Binding.ValidationRules> <DataErrorValidationRule /> </Binding.ValidationRules> </Binding> </TextBox.Text> </TextBox> <TextBox Margin="0,5,0,5" Text="{Binding Age, ValidatesOnDataErrors=True}" /> <Button Content="Reguster" /> <TextBlock Foreground="Red" Text="{Binding Error}" /> </StackPanel> </Window>
using GalaSoft.MvvmLight; using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Windows.Controls; namespace WpfApplication { public class MainWindowViewModel : ViewModelBase, IDataErrorInfo { private string userName; public string UserName { get { return userName; } set { userName = value; RaisePropertyChanged(nameof(UserName)); RaisePropertyChanged(nameof(Error)); } } private int age; public int Age { get { return age; } set { age = value; RaisePropertyChanged(nameof(Age)); RaisePropertyChanged(nameof(Error)); } } public string Error { get { var errors = new List<string> { this[nameof(UserName)], this[nameof(Age)] }; return string.Join(Environment.NewLine, errors.Where(s => !string.IsNullOrWhiteSpace(s))); } } public string this[string columnName] { get { if (columnName == nameof(UserName)) { if (string.IsNullOrWhiteSpace(UserName)) { return "User name is required"; } if(UserName.Length<6) { return "User name must be at least 6 characters long"; } if (UserName.Length > 10) { return "User name must be at most 10 characters long"; } } else if (columnName == nameof(Age)) { if (Age < 0) { return "You must be at least 0 years old"; } if (Age > 120) { return "You must be at most 120 years old"; } } return string.Empty; } } } }