Search code examples
wpfvalidationxamldata-bindingtooltip

WPF - ErrorTemplate tooltip showing on the Border but not one the TextBox


I have TextBox controls with a Binding to an integer property. They're like:

<TextBox x:Name="txtInteger"
         Grid.Row="2"
         Grid.Column="0"
         Text="{Binding Path=IntegerValue}"
         Validation.ErrorTemplate="{StaticResource ValidationForNumericValues}"/>

Predictably, ValidationForNumericValues is the validation error template:

<Window.Resources>
    <ControlTemplate x:Key="ValidationForNumericValues">
        <Grid>
            <Border BorderThickness="1"
                    BorderBrush="Red">
                <Border.ToolTip>
                    <ToolTip Placement="Right"
                             HorizontalOffset="5"
                             VerticalOffset="5"
                             Content="Please enter a number"/>
                </Border.ToolTip>
                <AdornedElementPlaceholder/>
            </Border>
        </Grid>
    </ControlTemplate>
</Window.Resources>

When I enter an alphanumeric value in txtInteger, the red border duly shows up, but I don't see the tooltip when the mouse cursor is within the TextBox. It only shows when the cursor is above the red border.

This answer suggests the DefaultBoxStyle might have something to do with it, but removing the <Style.../> declaration didn't improve things.

I also tried to use a different control, like

<Window.Resources>
    <ControlTemplate x:Key="ValidationForNumericValues">
        <Grid>
            <Border BorderThickness="1"
                    BorderBrush="Red">
                <Border.ToolTip>
                    <ToolTip Placement="Right"
                             HorizontalOffset="5"
                             VerticalOffset="5"
                             Content="Please enter a number"/>
                    </ToolTip>
                </Border.ToolTip>
                <TextBlock Text=""
                           Opacity="100"
                           Foreground="Red"
                           HorizontalAlignment="Stretch">
                    <TextBlock.ToolTip>
                        <ToolTip Placement="Right"
                                 HorizontalOffset="10"
                                 VerticalOffset="10"
                                 Content="Please enter a number"/>
                    </TextBlock.ToolTip>
                </TextBlock>
            </Border>
            <AdornedElementPlaceholder/>
        </Grid>
    </ControlTemplate>
</Window.Resources>

This lets the tooltip show up on the TextBox's whole surface... but I can't set the focus on it by clicking on it. I understand the TextBlock blocks it; I'd have thought that placing it before the AdornedElementPlaceholder would have put it under the TextBox, but I guess since it only appears conditionally, it always appear above.

(I've also tried the same thing with the TextBlock declared before the Border and the AdornedElementPlaceholder inside the Border, which I'm not including to save space, and had the same result.)

I've tried

<AdornedElementPlaceholder>
    <AdornedElementPlaceholder.ToolTip>
        <ToolTip Placement="Right"
                 HorizontalOffset="5"
                 VerticalOffset="5">
            <TextBlock>Please enter a number</TextBlock>
        </ToolTip>
    </AdornedElementPlaceholder.ToolTip>
</AdornedElementPlaceholder>

but that doesn't appear to affect the TextBox's ToolTip property, just that of AdornedElementPlaceholder.

I've tried to bind the TextBox's ToolTip property, but I can't figure out how to get to the Border's tooltip Content.

(In case it's relevant, I use a .NET 5.0 project under Visual Studio 2019.)

What did I do wrong?


Solution

  • Give your border a transparent background. A background (or content) is required for anything other than the borderline to be picked up when hit testing.

    <Border BorderThickness="1"
            BorderBrush="Red"
            Background="Transparent">