[ACCEPTED]-WPF Validation Errors: Setting Tooltip with Error Message-templates

Accepted answer
Score: 26

I know I'm late, but let me share a solution 7 I found studying this question: WPF custom validator with tooltip.

In it's 6 simplest form this ErrorTemplate shows only a Tooltip with the 5 ErrorContent for the whole AdornedElement.

<ControlTemplate x:Key="validationTemplate">
    <Grid Background="Transparent"
          ToolTip="{Binding Path=/ErrorContent}">
        <AdornedElementPlaceholder />
    </Grid>
</ControlTemplate>

But of course you can decorate 4 it as desired e.g. with a Tooltip for just a marker.

<ControlTemplate x:Key="validationTemplate">
    <Grid>
        <Ellipse Fill="Red" Opacity="0.8" Width="10" Height="10"
                 HorizontalAlignment="Right" VerticalAlignment="Top"
                 ToolTip="{Binding Path=/ErrorContent}" />
        <AdornedElementPlaceholder />
    </Grid>
</ControlTemplate>

Put 3 this Template in Resources and all you have to do is setting 2 the Validation.ErrorTemplate.

Validation.ErrorTemplate="{StaticResource validationTemplate}"

Even this annoying Trigger is no longer 1 needed.

<Style.Triggers>
    <Trigger Property="Validation.HasError" Value="True">
        <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
    </Trigger>
</Style.Triggers>
Score: 6

You can't place a tooltip on the AdornedElementPlaceholder, I 22 don't think it's visible at all, it's just 21 reserving space for whoever uses it (in 20 your case a TextBox). Looking at the Visual 19 Tree with Snoop we can see that the TemplatedAdorner 18 ends up in a different place in the VisualTree 17 than the TextBox so there will be now way 16 for us to find the TextBox from the VisualTree. We 15 can find it through AdornedElement, but 14 we still won't be able to set a tooltip.

alt text

The 13 only thing visible here in the TemplatedAdorner 12 is the Border. The Border knows its Child 11 - the TemplatedAdorner - which in turn knows 10 its AdornedElement - the TextBox. So we 9 could set the ToolTip for the Border with 8 this. (However, this Binding seems to fail 7 to update the Tooltip for the Border. It 6 works when I look at it with Snoop and after 5 that it displays.)

<Border BorderBrush="Red"
        BorderThickness="4"
        ToolTip="{Binding RelativeSource={RelativeSource self},
                  Path=Child.AdornedElement.(Validation.Errors)[0].ErrorContent}">

So, the TextBox has its 4 AttachedProperty Validation where we can 3 find the ErrorContent so it must set its 2 own ToolTip like you did at your last example, otherwise 1 it won't work.

Score: 2

I found a way to implement ToolTip with the returned 6 error message from the validation class 5 that you might create to validate your input.

First: Binding the error message

Adding 4 <Style> for the TextBox with Style.Trigger as followed:

<Style TargetType="{x:Type TextBox}" x:Key="ToolTipError">
    <!-- Some style setters -->
    <Style.Triggers>
        <Trigger Property="Validation.HasError" Value="true">
            <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
        </Trigger>
    </Style.Triggers>
</Style>

Second: Add the style to TextBox

<TextBox 
    Style="{StaticResource ToolTipError}"
    Validation.ErrorTemplate="{StaticResource validationTemplate}">
    <TextBox.Text>
        <Binding 
            Path="YourViewModelProperty"
            UpdateSourceTrigger="PropertyChanged"
            ValidatesOnNotifyDataErrors="True"
            ValidatesOnDataErrors="True"
            NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <ExceptionValidationRule:DateValidationRule ValidatesOnTargetUpdated="True"/>
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Bonus!

You can change 3 the ugly red border with other thing. For 2 example you can change it to red exclamation 1 mark:

<Window.Resources>
    <ControlTemplate x:Key="validationTemplate">
        <StackPanel>
            <TextBlock Text="!" FontSize="26" Foreground="Red"/>
            <AdornedElementPlaceholder/>
        </StackPanel>
    </ControlTemplate>
<Window.Resources>

More Related questions