ValidationErrorsHostBehavior Class
Tracks validation errors within a UI container.
Namespace: DevExpress.Mvvm.UI
Assembly: DevExpress.Xpf.Core.v24.1.dll
NuGet Package: DevExpress.Wpf.Core
Declaration
[TargetType(typeof(FrameworkElement))]
public class ValidationErrorsHostBehavior :
Behavior<FrameworkElement>
Remarks
You can define the ValidationErrorsHostBehavior for a UI container to track validation errors within it. To do this, set the Binding.NotifyOnValidationError and Binding.ValidatesOnDataErrors properties to true
for controls you want to validate.
Use the HasErrors property to check whether a bound UI container includes validation errors.
You can also use Validation Attributes with a ViewModelBase and POCO descendants.
Use the Behavior with ViewModelBase Descendants
To use the ValidationErrorsHostBehavior with ViewModeBase descendants, implement the IDataErrorInfo interface.
The following code sample enables validation for TextEdit controls. If they contain valid text, the Save button is enabled:
<UserControl
xmlns:ViewModels="clr-namespace:Example.ViewModels"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm">
<UserControl.DataContext>
<ViewModels:MainViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<dxmvvm:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:ValidationErrorsHostBehavior x:Name="validationErrorsHostBehavior"/>
</dxmvvm:Interaction.Behaviors>
<Grid>
<StackPanel Orientation="Vertical" ...>
<StackPanel Orientation="Horizontal">
<TextBlock Text="First Name: " .../>
<dxe:TextEdit Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True, ValidatesOnDataErrors=True}" .../>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Last Name: " .../>
<dxe:TextEdit Text="{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True, ValidatesOnDataErrors=True}" .../>
</StackPanel>
<Button Content="Login" ... IsEnabled="{Binding ElementName=validationErrorsHostBehavior,
Path=HasErrors, Converter={StaticResource BooleanNegationConverter}}"/>
</StackPanel>
</Grid>
</UserControl>
using DevExpress.Mvvm;
using System.ComponentModel;
namespace Example.ViewModel {
public class MainViewModel : ViewModelBase, IDataErrorInfo {
public string FirstName {
get { return GetValue<string>(); }
set { SetValue(value); }
}
public string LastName {
get { return GetValue<string>(); }
set { SetValue(value); }
}
public string Error {
get {
return this["FirstName"] != null || this["LastName"] != null ? "Invalid values." : null;
}
}
public string this[string columnName] {
get {
switch (columnName) {
case "FirstName":
return string.IsNullOrEmpty(FirstName) ? "First Name cannot be empty." : null;
case "LastName":
return string.IsNullOrEmpty(LastName) ? "Last Name cannot be empty." : null;
default:
return null;
}
}
}
}
}
Use the Behavior with POCO Descendants
You can set the POCO ViewModel’s ImplementIDataErrorInfo annotation attibute to true
to implement the IDataErrorInfo interface.
The following code sample enables validation for TextEdit controls. If they contain valid text, the Login button is enabled:
<UserControl
xmlns:ViewModels="clr-namespace:Example.ViewModels"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm">
<UserControl.DataContext>
<ViewModels:MainViewModel/>
</UserControl.DataContext>
<UserControl.Resources>
<dxmvvm:BooleanNegationConverter x:Key="BooleanNegationConverter"/>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:ValidationErrorsHostBehavior x:Name="validationErrorsHostBehavior"/>
</dxmvvm:Interaction.Behaviors>
<Grid>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
<TextBlock Text="First Name: " VerticalAlignment="Center" Width="71"/>
<dxe:TextEdit Text="{Binding FirstName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True, ValidatesOnDataErrors=True}" Width="120"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="0,0,0,10">
<TextBlock Text="Last Name: " VerticalAlignment="Center" Width="71"/>
<dxe:TextEdit Text="{Binding LastName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True, ValidatesOnDataErrors=True}" Width="120"/>
</StackPanel>
<Button Content="Login" HorizontalAlignment="Center" VerticalAlignment="Center" IsEnabled="{Binding ElementName=validationErrorsHostBehavior,
Path=HasErrors, Converter={StaticResource BooleanNegationConverter}}"/>
</StackPanel>
</Grid>
</UserControl>
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using System.ComponentModel.DataAnnotations;
// ...
[POCOViewModel(ImplementIDataErrorInfo = true)]
public class MainViewModel {
[Required]
public virtual string FirstName { get; set; }
[Required]
public virtual string LastName { get; set; }
}
}
Tip
Refer to the following topic for information on how to use validation attributes with POCO: Automatic IDataErrorInfo Implementation.
Use Validation Attributes
You can specify ValidationAttribute descendants to define ValidationErrorsHostBehavior‘s validation rules.
The following ViewModel checks whether FirstName and LastName are not empty and their values do not contain more that 40 letters and apostrophes:
using DevExpress.Mvvm;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
// ...
public class MainViewModel : ViewModelBase, IDataErrorInfo {
protected string firstname_;
[Required]
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")]
public string FirstName {
get { return this.firstname_; }
set { this.SetProperty(ref this.firstname_, value, "FirstName"); }
}
protected string lastname_;
[Required]
[RegularExpression(@"^[a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Characters are not allowed.")]
public string LastName {
get { return this.lastname_; }
set { this.SetProperty(ref this.lastname_, value, "LastName"); }
}
// ...
}