Mike Woolf
Mike Woolf

Reputation: 1210

WPF TextBox Red Border Still Displayed After ValidationRule succeeds

I have a textbox with a very simple ValidationRule:

<TextBox x:Name="textFirstName" Width="120">
    <TextBox.Text>
        <Binding
           Path="CurrentSelectionData.Tables[cpeople].Rows[0][FirstName]"
           UpdateSourceTrigger="PropertyChanged">
           <Binding.ValidationRules>
               <local:NonEmptyStringValidationRule ValidatesOnTargetUpdated="True"/>
           </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

public class NonEmptyStringValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
            return new ValidationResult(false, "Must provide a value.");

        return ValidationResult.ValidResult;
    }
}

The problem is that the red validation error border displays on start-up even though the textbox is bound to non-empty data.

Watching a breakpoint on the validation rule, I see that it is called once for an empty string (before the binding is changed to valid data) and once again after the binding updates to valid data. Sure enough, the second call returns ValidResult, yet the red border remains.

Manually clearing the textbox and typing new text into it clears the red border, but simply typing new text into it without first clearing it does not.

The one potential trickiness I can see, from reading other folks' questions, is that this TextBox is in a tab control. However, my problem is the opposite of those other folks (they weren't getting a red border despite a failed validation), nor am I moving to a different tab control at any point (which was the cause of the other issues).

Any ideas what I'm missing here?

Upvotes: 2

Views: 4407

Answers (2)

Mike Woolf
Mike Woolf

Reputation: 1210

It turns out that changing validated bound data during a Window's Loaded event caused the problem. In my case, the problem was solved by performing the data change during Initialized or ContentRendered instead. Initialized has the advantage of happening before the first (invalid) binding, thus avoiding a temporary red border to flash up during app load.

Upvotes: 2

sa_ddam213
sa_ddam213

Reputation: 43596

I tried to replicate your issue but it seems to work ok in my tests, so the problem must be with the data you are binding to as you said the validationRule is working fine.

Is the Table your binding to TwoWay?

My Test:

xaml:

<TextBox x:Name="textFirstName" Width="120" ToolTip="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}">
    <TextBox.Text>
        <Binding ElementName="UI" Path="TextTest" UpdateSourceTrigger="PropertyChanged" ValidatesOnDataErrors="True" >
            <Binding.ValidationRules>
                <local:NonEmptyStringValidationRule ValidatesOnTargetUpdated="True"  />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

code:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private string _textTest;
    public string TextTest
    {
        get { return _textTest ; }
        set { _textTest = value; }
    }
}

public class NonEmptyStringValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        return (value is string && !string.IsNullOrEmpty(value.ToString()))
            ? new ValidationResult(true, null)
            : new ValidationResult(false, "Invalid Text");
    }
}

Upvotes: 0

Related Questions