WPF Validation ErrorTemplate errorcontent tooltip not working

558 Views Asked by At

I'm not sure if I'm missing something simple or not. I'm thinking maybe a binding needs to change possibly? Or maybe its not properly targeting the TextBox for the ErrorContent?

I think it's worth noting that neither example produces a binding error.

If I have the below XAML defined in my App.xml, when my field is validated, everything looks like it should be working, but the tooltip is not working because ErrorContent seems to be blank, if I change that binding in the tooltip to "Test" the tooltip shows "Test".

<Style BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox">
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel>
                    <Image
                        Height="24"
                        Margin="-28,0,0,0"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        DockPanel.Dock="Right"
                        Source="/Resources/error-96.png"
                        ToolTip="{Binding /ErrorContent}" />
                    <AdornedElementPlaceholder />
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Screenshot of field validation tooltip not working

If I add to that same XAML some triggers to set the border colors etc, the tooltip then magically starts working, seen below.

<Style BasedOn="{StaticResource DefaultTextBoxStyle}" TargetType="TextBox">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border
                    x:Name="border"
                    Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    SnapsToDevicePixels="True"
                    UseLayoutRounding="True">
                    <ScrollViewer
                        x:Name="PART_ContentHost"
                        Focusable="false"
                        HorizontalScrollBarVisibility="Hidden"
                        VerticalScrollBarVisibility="Hidden" />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Trigger.Setters>
                            <Setter Property="BorderBrush" Value="Red" />
                            <Setter Property="BorderThickness" Value="3" />
                        </Trigger.Setters>
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="Validation.HasError" Value="false" />
                            <Condition Property="IsMouseOver" Value="true" />
                        </MultiTrigger.Conditions>
                        <MultiTrigger.Setters>
                            <Setter TargetName="border" Property="BorderBrush" Value="#FF7EB4EA" />
                        </MultiTrigger.Setters>
                    </MultiTrigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="border" Property="Opacity" Value="0.56" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Validation.ErrorTemplate">
        <Setter.Value>
            <ControlTemplate>
                <DockPanel>
                    <Image
                        Height="24"
                        Margin="-28,0,0,0"
                        HorizontalAlignment="Stretch"
                        VerticalAlignment="Stretch"
                        DockPanel.Dock="Right"
                        Source="/Resources/error-96.png"
                        ToolTip="{Binding /ErrorContent}" />
                    <AdornedElementPlaceholder />
                </DockPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Screenshot of field validation tooltip working

Incase you want to see the textbox binding, which works to show the ErrorTemplate.

<TextBox
        Margin="0,2.5,2.5,2.5"
        HorizontalAlignment="Stretch"
        ui:ControlHelper.PlaceholderText="IPv4 Address"
        ui:TextBoxHelper.IsDeleteButtonVisible="False"
        Text="{Binding EditServerModel.IPAddress, ValidatesOnDataErrors=True}" />

My main reason for not wanting to use the second one is it replaces the template of the DefaultTextBoxStyle and breaks the placerholder text in the textboxes, along with some other special features, all I really want/need is the part that shows the error image with a tooltip.

Edit: I'm using CommunityToolkit.MvvM. My models implement ObservableValidator, which implements INotifyDataErrorInfo. My properties in my models use DataAnnotation attributes such as [Required] and [RegularExpression]

An example:

public class ServerModel : ObservableValidator
{
    private string _iPAddress;
    
    [Required]
    [RegularExpression(@"^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$", ErrorMessage = "Not a valid IPv4 address.")]
    public string IPAddress
    {
        get => _iPAddress;
        set
        {
            SetProperty(ref _iPAddress, value);
            ValidateProperty(value);
        }
    }
}

Edit - Working answer:

I ended up copying the default style from the ModernWpf project and removing primitives:ValidationHelper.IsTemplateValidationAdornerSite="True" so that I could use my own validation template.

1

There are 1 best solutions below

6
mm8 On BEST ANSWER

Try this binding:

ToolTip="{Binding [0].ErrorContent}"

It this doesn't work, the issue is related to the DefaultTextBoxStyle.