Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Validation Errors: Setting Tooltip with Error Message

Why is there no tooltip text on errors?

<Style TargetType="{x:Type TextBox}">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <StackPanel>
                    <Border ...>
                        <AdornedElementPlaceholder ... 
                            ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
                    </Border>
                    ...
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

I also noticed that

<AdornedElementPlaceholder ...
    ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />

fails but the below suceeds, even with the same binding, why is this so? Doesn't AdornedElementPlaceholder refer to the text box? Even if it doesn't, shouldn't a tooltip appear somewhere?

<Style.Triggers>
    <Trigger Property="Validation.HasError" Value="True">
        <Setter Property="ToolTip" Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
    </Trigger>
</Style.Triggers>
like image 809
Jiew Meng Avatar asked Nov 12 '10 04:11

Jiew Meng


2 Answers

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

In it's simplest form this ErrorTemplate shows only a Tooltip with the 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 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 this Template in Resources and all you have to do is setting the Validation.ErrorTemplate.

Validation.ErrorTemplate="{StaticResource validationTemplate}"

Even this annoying Trigger is no longer 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>
like image 95
LPL Avatar answered Dec 04 '22 06:12

LPL


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

alt text

The only thing visible here in the TemplatedAdorner is the Border. The Border knows its Child - the TemplatedAdorner - which in turn knows its AdornedElement - the TextBox. So we could set the ToolTip for the Border with this. (However, this Binding seems to fail to update the Tooltip for the Border. It works when I look at it with Snoop and after 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 AttachedProperty Validation where we can find the ErrorContent so it must set its own ToolTip like you did at your last example, otherwise it won't work.

like image 32
Fredrik Hedblad Avatar answered Dec 04 '22 08:12

Fredrik Hedblad