Piotr Golacki
Piotr Golacki

Reputation: 206

Customize the default Validation.ErrorTemplate

EDIT:

The posted answer is really useful because it contained a hint that I should bind to EditingElementStyle and it helped to solve an underlying problem I had i.e. when putting a alphabetic value into a textbox accepting only numerical values I couldn't change the underlying error template.

Old question:

I have seemingly simple problem as I want to override the default validation error template in WPF (the red border) I thought I knew how to do it after reading some answers on SO and documentation, but somehow I cannot make it to work.

XAML:

<Window x:Class="WpfTestApp.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfTestApp"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
    <local:ViewModel></local:ViewModel>
</Window.DataContext>
<Window.Resources>
    <Style TargetType="{x:Type TextBox}">
       <Style.Setters>
             <Setter Property="Validation.ErrorTemplate" >
                <Setter.Value>
                    <ControlTemplate>
                        <StackPanel Background="Aqua">
                            </StackPanel>
                        
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style.Setters>
    </Style>
</Window.Resources>
<Grid>
    <DataGrid x:Name="sampleDataGrid" ItemsSource="{Binding Customers}" AutoGenerateColumns="False" CanUserDeleteRows="True">
        
        <DataGrid.Columns>
            <DataGridTextColumn Header="Age" >
                <DataGridTextColumn.Binding>
                    <Binding Path="Age">
                        <Binding.ValidationRules>
                            <local:AgeValidationRuleUnder18></local:AgeValidationRuleUnder18>
                        </Binding.ValidationRules>
                    </Binding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>

        </DataGrid.Columns>
        
    </DataGrid>
</Grid>

Upvotes: 0

Views: 1649

Answers (1)

BionicCode
BionicCode

Reputation: 28968

You must apply the error Style to the DataGridBoundColumn.EditingElementStyle property.

First define the error template properly using the AdornedElementPlaceholder. Add the ControlTemplate to a ResourceDictionary within the scope of usage e.g. Application.Resources in App.xaml:

<ControlTemplate x:Key="ValidationErrorTemplate">
  <Border BorderBrush="Red" 
          BorderThickness="2">
    <StackPanel>
      <!-- Placeholder for the DataGridTextColumn itself -->
      <AdornedElementPlaceholder x:Name="AdornedElement" />
      
      <Popup PlacementTarget="{Binding ElementName=AdornedElement}" 
             IsOpen="True">
        <TextBlock Text="{Binding /ErrorContent}" 
                   Foreground="Red" 
                   Background="White"/>
      </Popup>
    </StackPanel>
  </Border>
</ControlTemplate>

Then define the column's editing Style that assigns the validation error template to the attached property Validation.ErrorTemplate. Add this Style to a ResourceDictionary within the scope of the DataGrid e.g. DataGrid.Resources:

<Style x:Key="ValidationErrorStyle" TargetType="TextBox">
  <Setter Property="Validation.ErrorTemplate" 
          Value="{StaticResource ValidationErrorTemplate}" />
</Style>

Apply the Style on the column by setting the EditingElementStyle property:

<DataGrid.Columns>
  <DataGridTextColumn Header="Age"
                      EditingElementStyle="{StaticResource ValidationErrorStyle}">
    <DataGridTextColumn.Binding>
      <Binding Path="Age">
        <Binding.ValidationRules>
          <local:AgeValidationRuleUnder18 />
        </Binding.ValidationRules>
      </Binding>
    </DataGridTextColumn.Binding>
  </DataGridTextColumn>
</DataGrid.Columns>

Upvotes: 2

Related Questions