简体   繁体   中英

How to validate user input in a textbox with updateSourceTrigger=“Explicit” with xaml:C#?

I'm new in WPF/XAML and I need help. I didn't found a response to my question in the existing questions/answers or I failed in using them. I have a wpf application with several textboxes, checkboxes and comboboxes: all are binded to properties of my Object. I have also a cancel and a validate buttons. To not update the properties bind to my textboxes (and etc...), I used UpdateSourceTrigger ="Explicit". I would like to use a ValidationRule when Focus is lost on my email address text box but I don't know how to do.

My XAML is:

<TextBox Margin="5 0 5 0" x:Name="txtBox_mailSender"  
                                     Validation.ErrorTemplate="{StaticResource ValidationTemplate}">
                            <TextBox.Text>
                                <Binding Path="SenderMailAddress"
                                         UpdateSourceTrigger="Explicit">
                                    <Binding.ValidationRules>
                                        <local:EmailAddressValidator />
                                    </Binding.ValidationRules>
                                </Binding>
                            </TextBox.Text>
                        </TextBox>

My EmailAddressValidator:

public class EmailAddressValidator : ValidationRule
{
    //public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    //{
    //  Regex mailAddressRegex = new Regex(@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" +
    //        @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" +
    //        @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");

    //  if(!mailAddressRegex.IsMatch((string)value))
    //  {
    //      return new ValidationResult(false, $"Adresse E-mail invalide.");
    //  }
    //  return new ValidationResult(true, null);
    //}

    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        try
        {
            new MailAddress(value.ToString());

        }
        catch (Exception)
        {
            return new ValidationResult(false, "Adresse E-mail invalide.");
        }

        return new ValidationResult(true, null);
    }
}

My Control Template (Validation Template) but I think it's not necessary since the red border is good for me:

<ControlTemplate x:Key="ValidationTemplate">
    <DockPanel>
        <TextBlock Foreground="Red" >!</TextBlock>
        <AdornedElementPlaceholder/>
    </DockPanel>
</ControlTemplate>

I tried with the LostFocus event but I don't know how to transform the textbox into a "textbox with errors".

An extract of my object with the e-mail property:

public class MyObject
{
    public String SenderMailAddress
            {
                set
                {
                    if (SenderMailAddress != value)
                    {
                        _senderMailAddress = value;
                        OnSpecificModification();
                    }
                }
                get
                {
                    return _senderMailAddress;
                }
            }
            private String _senderMailAddress = "";
 }

Thank you for your help.

To use UpdateSourceTrigger="Explicit" you need to set the binding as "TwoWay" or "OneWayToSource". Then you need to call the UpdateSource on the binding. Maybe in a LostFocus event handler on the TextBox or when you press the ValidateButton. This is when the validation will occur and the Object property will be updated if the validation is passed.

Set TwoWay:

<Binding Path="SenderMailAddress" Mode="TwoWay"

UpdateSource:

    txtBox_mailSender.GetBindingExpression(TextBox.TextProperty).UpdateSource();

I think your validationTemplate works. Observe the tiny exclamation point in front of the textbox.

You should look into the MVVM pattern. This will give you a lot more control and separation of your program.

Finally, I used:

private void txtBox_mailSender_LostFocus(object sender, RoutedEventArgs e)
    {
        txtBox_mailSender.GetBindingExpression(TextBox.TextProperty).ValidateWithoutUpdate();

    }

and in my textbox

UpdateSourceTrigger="Explicit"

without specifying the binding mode.

With ValidateWithoutUpdate(), the validation rules are performed without updating the source as I wanted because I have a Validate Button in which I update the source with

txtBox_mailSender.GetBindingExpression(TextBox.TextProperty).UpdateSource();

I found this answer thanks to RolandJS and because I took a look at all the possible expressions after GetBindingExpression(TextBox.TextProperty). .

Thank you to everyone for your help: Have a good day! Mine will be better now :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM