In addition to the essential Errors and HasError properties, the Validation class also declares an ErrorTemplate Attached Property of the ControlTemplate type. The default template assigned to this property is responsible for defining the red rectangle that surrounds UI fields that have validation errors associated with them.
However, this property enables us to change this template and so, we are able to define how validation errors are highlighted to the application users. As this property is an Attached Property, this effectively means that we could apply a different template to be displayed for each control in the UI. However, this cannot be recommended because it could make the application look less consistent.
This template actually uses an Adorner element to render its graphics in the adorner layer, on top of the related control in error. Therefore, in order to specify where our error visual(s) should be rendered in relation to the related control, we need to declare an AdornedElementPlaceholder element in the error template.
Let's take a look at a simple example, where we define a slightly thicker, non-blurry border, unlike the default one, and paint over the background of the related control with feint red for added emphasis. We first need to define a ControlTemplate object in a suitable resource section:
<ControlTemplate x:Key="ErrorTemplate"> <Border BorderBrush="Red" BorderThickness="2" Background="#1FFF0000" SnapsToDevicePixels="True"> <AdornedElementPlaceholder /> </Border> </ControlTemplate>
In this example, we declare the AdornedElementPlaceholder element inside a Border element, so that the border will be rendered around the outside of the related control. Note that without declaring this AdornedElementPlaceholder element, our border would resemble a tiny red dot in the top left of the related control when an error occurred.
Now, let's see how we apply this template, using our earlier example of the control that was data bound to the Product.Price property:
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Products.CurrentItem.Price, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True, Delay=250}" Style="{StaticResource FieldStyle}" Validation.ErrorTemplate="{StaticResource ErrorTemplate}" />
Now, let's see what it looks like when rendered:

If we wanted to position our error highlighting elements in a different position with relation to the related control in error, we could use one of the panels to position them. Let's take a look at a slightly more advanced error template that we could use. Let's begin by declaring some resources in a suitable resource section:
<ToolTip x:Key="ValidationErrorsToolTip"> <ItemsControl ItemsSource="{Binding}"> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding ErrorContent}" /> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </ToolTip> <ControlTemplate x:Key="WarningErrorTemplate"> <StackPanel Orientation="Horizontal">
<AdornedElementPlaceholder Margin="0,0,10,0" />
<Image Source="pack://application:,,,/CompanyName.ApplicationName;
component/Images/Warning_16.png" Stretch="None"
ToolTip="{StaticResource ValidationErrorsToolTip}" />
</StackPanel> </ControlTemplate>
In this example, we declare a ToolTip resource named ValidationErrorsToolTip. In it, we declare an ItemsControl element to display all of the validation errors together. We define a DataTemplate element in the ItemTemplate property, which will output the value of the ErrorContent property of each ValidationError object in the Validation.Errors collection. This collection will be implicitly set as the data context of the control template.
Next, we declare a ControlTemplate element to set to the ErrorTemplate property, with the WarningErrorTemplate key. In it, we define a horizontal StackPanel control and, within that, we declare the required AdornedElementPlaceholder element. This is followed by the warning icon, taken from the Visual Studio icon set, that was discussed in Chapter 8, Creating Visually Appealing User Interfaces, with the ValidationErrorsToolTip resource applied to its ToolTip property.
We can apply this template using the ErrorTemplate property as follows:
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Products.CurrentItem.Price, UpdateSourceTrigger=PropertyChanged, ValidatesOnNotifyDataErrors=True, Delay=250}" Style="{StaticResource FieldStyle}" Validation.ErrorTemplate="{StaticResource WarningErrorTemplate}" />
When a validation error now occurs on this TextBox control, it will look like this:

Now that we've investigated a variety of ways to display our validation errors, let's move on to explore how we can avoid UI-based validation errors altogether.