nam
nam

Reputation: 23749

WPF ValidationRule Binding to display the error message

In the following code, I am using ValidationRule to validate user input on a TextBox. It works fine. If user enters invalid data (any non-alphabet character) it displays a small red ! sign on the left of the textbox, and also if you mouseover the textbox it would display an invalid data message (as shown in the image below).

Question: How can we modify the following code so - instead of tooltip, the invalid data message is displayed just below the textbox?

Remarks: I tried replacing ToolTip with TexBlock in the following line <Setter Property="ToolTip" of the XAML below, and put a textblock below TexBox as follows: <TextBlock Text="{Binding (Validation.Errors)[0].ErrorContent, ElementName=txtTest}"/>. But (as expected) it did not work since TextBlock, of course, is not a property of TextBox

MyDataSource.cs:

public class MyDataSource
{
public MyDataSource()
{

}

public string FirstName { get; set; }
}

AlphabetsOnlyValidationRule:

public class AlphabetsOnlyValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        string sVal = value as string;

        if (string.IsNullOrEmpty(sVal))
        {
            return new ValidationResult(false, "Please enter some text");
        }

        if (!sVal.ToList().All(t => char.IsLetter(t)))
        {
            return new ValidationResult(false, "First Name should contains alphabets only");
        }

        return new ValidationResult(true, null);
    }
}

MainWindow.xaml:

<Window.Resources>
    <local:MyDataSource x:Key="Ods"/>
    <local:AlphabetsOnlyValidationRule x:Key="AlphabetsOnlyKey"/>
    
    <ControlTemplate x:Key="ValidationTemplate">
        <DockPanel>
            <TextBlock Foreground="Red" FontSize="20">!</TextBlock>
            <AdornedElementPlaceholder/>
        </DockPanel>
    </ControlTemplate>

    <Style x:Key="TextBoxInError" TargetType="{x:Type TextBox}">
        <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>
</Window.Resources>
<Grid>
    <TextBox x:Name="txtTest" Margin="48,0,572,388" Style="{StaticResource TextBoxInError}" Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
        <TextBox.Text>
            <Binding Path="FirstName" Source="{StaticResource Ods}" UpdateSourceTrigger="PropertyChanged" >
                <Binding.ValidationRules>
                    <local:AlphabetsOnlyValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
    </TextBox>
</Grid>

Screenshot of Validation Message [When user enters non-alphabet character]

enter image description here

Upvotes: 0

Views: 1420

Answers (1)

mm8
mm8

Reputation: 169200

Add a TextBlock that binds to the ErrorContent property to the Validation.ErrorTemplate:

<ControlTemplate x:Key="ValidationTemplate">
    <DockPanel>
        <TextBlock Foreground="Red" FontSize="20" DockPanel.Dock="Left">!</TextBlock>
        <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red" DockPanel.Dock="Bottom"/>
        <AdornedElementPlaceholder/>
    </DockPanel>
</ControlTemplate>

Upvotes: 2

Related Questions