Joe
Joe

Reputation: 1326

Return Focus to WPF Element when contents fail validation

I am validating the data entered in a TextBox when it looses the Focus. When my validation rule identifies the contents of a TextBox as invalid I would like to automatically return the Focus back to the TextBox. My reasoning is that if the user has to reenter valid data I can save him a keystroke by prepositioning the cursor for them.

I pass the name of the TextBox through to the validation class like so ...

<TextBox x:Name="addAnInteger">
<Binding.ValidationRules>                                            
     <local:ValidateInteger32 TextBoxName="addAnInteger"/>                                                     
</Binding.ValidationRules>
</TextBox>

In the validation class (ValidateInteger32) I have:

public string TextBoxName { get; set; }

The property TextBoxName receives and stores the name of the TextBox that I want to reset the Focus to.

How can I set the Focus back to the "addAnInteger" TextBox from inside the ValidateInteger32 validation class using only the name of the property TextBoxName? I'm thinking something like ....

[Commands that expose the contents of TextBoxName].Focus();

I don't want to use the name of individual TextBoxes in the validation class because I want the class to be generic.

Grateful for any advice.

Upvotes: 1

Views: 1212

Answers (2)

mm8
mm8

Reputation: 169210

The ValidationRule simply returns a ValidationResult. It has doesn't know anything about the TextBox in the view.

It is the responsibility of the control/view itself to act on the validation result. You could for example handle the Validation.Error event like this:

private void addAnInteger_Error(object sender, ValidationErrorEventArgs e)
{
    TextBox textBox = (TextBox)sender;
    textBox.Dispatcher.BeginInvoke(new Action(() => { Keyboard.Focus(textBox); }), System.Windows.Threading.DispatcherPriority.Background);
}

XAML:

<TextBox x:Name="addAnInteger" Margin="10" Validation.Error="addAnInteger_Error">
    <TextBox.Text>
        <Binding Path="Text" NotifyOnValidationError="True">
            <Binding.ValidationRules>
                <local:ValidateInteger32 />
            </Binding.ValidationRules>
        </Binding>
    </TextBox.Text>
</TextBox>

Or you will have to bind the a reference to the actual TextBox to the ValidationRule somehow. Please refer to my answer here for more information about this:

How to bind values from xaml to validation rule?

Upvotes: 1

WPFUser
WPFUser

Reputation: 1175

You can use Validation.Error event. you will get Instance there.

take a look at this: Validation.error event in event command

Upvotes: 1

Related Questions