wpf-devexpress-dot-mvvm-dot-ui-fd475c52.md
Tracks validation errors within a UI container.
Namespace : DevExpress.Mvvm.UI
Assembly : DevExpress.Xpf.Core.v25.2.dll
NuGet Package : DevExpress.Wpf.Core
[TargetType(typeof(FrameworkElement))]
public class ValidationErrorsHostBehavior :
Behavior<FrameworkElement>
<TargetType(GetType(FrameworkElement))>
Public Class ValidationErrorsHostBehavior
Inherits Behavior(Of FrameworkElement)
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.
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;
}
}
}
}
}
Imports DevExpress.Mvvm
Imports System.ComponentModel
Namespace Example.ViewModel
Public Class MainViewModel
Inherits ViewModelBase
Implements IDataErrorInfo
Public Property FirstName As String
Get
Return GetValue(Of String)()
End Get
Set(ByVal value As String)
SetValue(value)
End Set
End Property
Public Property LastName As String
Get
Return GetValue(Of String)()
End Get
Set(ByVal value As String)
SetValue(value)
End Set
End Property
Public ReadOnly Property [Error] As String
Get
Return If(Me("FirstName") IsNot Nothing OrElse Me("LastName") IsNot Nothing, "Invalid values.", Nothing)
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String
Get
Select Case columnName
Case "FirstName"
Return If(String.IsNullOrEmpty(FirstName), "First Name cannot be empty.", Nothing)
Case "LastName"
Return If(String.IsNullOrEmpty(LastName), "Last Name cannot be empty.", Nothing)
Case Else
Return Nothing
End Select
End Get
End Property
End Class
End Namespace
You can set the POCO ViewModel’s ImplementIDataErrorInfo annotation attibute to trueto 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; }
}
}
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
Imports System.ComponentModel.DataAnnotations
Namespace Example.ViewModel
<POCOViewModel(ImplementIDataErrorInfo:=True)>
Public Class MainViewModel
<Required>
Public Overridable Property FirstName() As String
<Required>
Public Overridable Property LastName() As String
End Class
End Namespace
Tip
Refer to the following topic for information on how to use validation attributes with POCO : Automatic IDataErrorInfo Implementation.
View Example: WPF MVVM Framework - Validate a View with ValidationErrorsHostBehavior and POCO
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"); }
}
// ...
}
Imports DevExpress.Mvvm
Imports System.ComponentModel
Imports System.ComponentModel.DataAnnotations
Namespace ValidationErrorHostBehavior.ViewModels
Public Class MainViewModel
Inherits ViewModelBase
Implements IDataErrorInfo
Protected firstname_ As String
<Required>
<RegularExpression("^[a-zA-Z''-'\s]{1,40}$", ErrorMessage := "Characters are not allowed.")>
Public Property FirstName() As String
Get
Return Me.firstname_
End Get
Set(ByVal value As String)
Me.SetProperty(Me.firstname_, value, "FirstName")
End Set
End Property
Protected lastname_ As String
<Required>
<RegularExpression("^[a-zA-Z''-'\s]{1,40}$", ErrorMessage := "Characters are not allowed.")>
Public Property LastName() As String
Get
Return Me.lastname_
End Get
Set(ByVal value As String)
Me.SetProperty(Me.lastname_, value, "LastName")
End Set
End Property
Public ReadOnly Property Error As String Implements IDataErrorInfo.Error
Get
Return String.Join(";", Me("FirstName"), Me("LastName"))
End Get
End Property
Default Public ReadOnly Property Item(ByVal columnName As String) As String Implements IDataErrorInfo.Item
Get
Return IDataErrorInfoHelper.GetErrorText(Me, columnName)
End Get
End Property
End Class
End Namespace
Run Demo: Behaviors Module in the WPF MVVM Demo
Object DispatcherObject DependencyObject Freezable Animatable DevExpress.Mvvm.UI.Interactivity.AttachableObjectBase DevExpress.Mvvm.UI.Interactivity.Behavior DevExpress.Mvvm.UI.Interactivity.Behavior<FrameworkElement> ValidationErrorsHostBehavior
See Also
ValidationErrorsHostBehavior Members