Wpf – Show the validation error template on a different control in WPF

templatesvalidationwpf

I have a UserControl that contains other controls and a TextBox. It has a Value property that is bound to the TextBox text and has ValidatesOnDataErrors set to True.

When a validation error occurs in the Value property binding, the error template (standard red border) is shown around the entire UserControl.

Is there a way to show it around the TextBox only?
I'd like to be able to use any error template so simply putting border around textbox and binding its color or something to Validation.HasError is not an option.

Here's my code:

<DataTemplate x:Key="TextFieldDataTemplate">
    <c:TextField DisplayName="{Binding Name}" Value="{Binding Value, Mode=TwoWay, ValidatesOnDataErrors=True}"/>
</DataTemplate>

<controls:FieldBase x:Name="root">
<DockPanel DataContext="{Binding ElementName=root}">
    <TextBlock Text="{Binding DisplayName}"/>
    <TextBox x:Name="txtBox"                 
             Text="{Binding Value, Mode=TwoWay, ValidatesOnDataErrors=True}"
             IsReadOnly="{Binding IsReadOnly}"/>
</DockPanel>

UserControl (FieldBase) is than bound to ModelView which performs validation.

Best Answer

to accomplish this task I've used this solution. It uses converter, that "hides" border by converting (Validation.Errors).CurrentItem to Thickness.

<Grid>
    <Grid.Resources>
        <data:ValidationBorderConverter
            x:Key="ValidationBorderConverter" />
    </Grid.Resources>
    <Border
        BorderBrush="#ff0000"
        BorderThickness="{Binding 
            ElementName=myControl, 
            Path=(Validation.Errors).CurrentItem, 
            onverter={StaticResource ValidationBorderConverter}}">
        <TextBox
            ToolTip="{Binding 
                ElementName=myControl, 
                Path=(Validation.Errors).CurrentItem.ErrorContent}" />
    </Border>
</Grid>

ValidationBorderConverter class is pretty simple:

[ValueConversion(typeof(object), typeof(ValidationError))]
public sealed class ValidationBorderConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
    {
        return (value == null) ? new Thickness(0) : new Thickness(1);
    }

    public object ConvertBack(object value, Type targetType, object parameter, 
            System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
Related Topic