WPF Binding Validation data verification

Source: Internet
Author: User

Table data verification is often boring and unavoidable.
If the following form has only two input boxes and a confirmation button, what do we need to do normally?

 

1. If a non-numeric string is entered in the age input box and the input box loses focus, the following error message should be immediately prompted.

2. If the content of the error message changes, you may need to modify the overall uidesign (for example, it is displayed below the input box)

3. Click the OK button to traverse all input boxes in the Window. If any input data does not match the verification result, an error is prompted and the corresponding control gets the focus.

Is this easy? What if there are more input boxes?

The following Demo shows how WPF can easily handle these issues:

In the Window, textBox1, textBox2, and textBox3 are bound to the following data:

DataSource    public class MyDataSource    {        private int _age;        private int _age2;        private int _age3;        public MyDataSource()        {            Age = 0;            Age2 = 0;        }        public int Age        {            get { return _age; }            set { _age = value; }        }        public int Age2        {            get { return _age2; }            set { _age2 = value; }        }        public int Age3        {            get { return _age3; }            set { _age3 = value; }        }    }
  • Use custom verification rules
<TextBox Name="textBox1" Width="50" FontSize="15"         Validation.ErrorTemplate="{StaticResource validationTemplate}"         Style="{StaticResource textBoxInError}"         Grid.Row="1" Grid.Column="1" Margin="2">  <TextBox.Text>    <Binding Path="Age" Source="{StaticResource ods}"             UpdateSourceTrigger="PropertyChanged" >      <Binding.ValidationRules>        <c:AgeRangeRule Min="21" Max="130"/>      </Binding.ValidationRules>    </Binding>  </TextBox.Text></TextBox>
 

TextBox1 is bound with Age and uses the verification rule AgeRangeRule. The minimum and maximum values are specified in the rule. When PropertyChanged, the verification rule is triggered, that is, when the control loses focus. the prompt information style is defined in ErrorTemplate. Let's take a look at ErrroTemplate content:

      <ControlTemplate x:Key="validationTemplate">        <DockPanel>          <TextBlock Foreground="Red" FontSize="20">!</TextBlock>          <AdornedElementPlaceholder/>        </DockPanel>      </ControlTemplate>

AdornedElementPlaceholder is the focus here, where the control to be verified is placed, and the entire ErrorTemplate uses the magic Adoner to achieve the error prompt location and the original layout is irrelevant. the verification rules are completely decoupled from the entire code:

rule public class AgeRangeRule : ValidationRule    {        private int _min;        private int _max;        public AgeRangeRule()        {        }        public int Min        {            get { return _min; }            set { _min = value; }        }        public int Max        {            get { return _max; }            set { _max = value; }        }        public override ValidationResult Validate(object value, CultureInfo cultureInfo)        {            int age = 0;            try            {                if (((string)value).Length > 0)                    age = Int32.Parse((String)value);            }            catch (Exception e)            {                return new ValidationResult(false, "Illegal characters or " + e.Message);            }            if ((age < Min) || (age > Max))            {                return new ValidationResult(false,                  "Please enter an age in the range: " + Min + " - " + Max + ".");            }            else            {                return new ValidationResult(true, null);            }        }    }

The exception thrown when the verification rule fails is displayed in the Tip.

     <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>
  • Use predictionvalidationrule

Another method, such:

 <TextBox Name="textBox3" Width="50" FontSize="15"             Grid.Row="5" Grid.Column="1" Margin="2"             Validation.ErrorTemplate="{StaticResource validationTemplate}"             Style="{StaticResource textBoxInError}">      <TextBox.Text>        <Binding Path="Age3" Source="{StaticResource ods}"                 UpdateSourceTrigger="PropertyChanged">          <Binding.ValidationRules>            <ExceptionValidationRule/>          </Binding.ValidationRules>        </Binding>      </TextBox.Text>    </TextBox>

In the background code:

 
        BindingExpression myBindingExpression = textBox3.GetBindingExpression(TextBox.TextProperty);            Binding myBinding = myBindingExpression.ParentBinding;            myBinding.UpdateSourceExceptionFilter = new UpdateSourceExceptionFilterCallback(ReturnExceptionHandler);            myBindingExpression.UpdateSource();
 

Because Age3 is of the Int type, inputting a non-int type in textBox3 will cause an exception. In this case, the system uses the Rule ExceptionValidationRule, and the module with the same error information remains unchanged.

  • Verify all controls
          // Validate all dependency objects in a window        bool IsValid(DependencyObject node)        {            // Check if dependency object was passed            if (node != null)            {                // Check if dependency object is valid.                // NOTE: Validation.GetHasError works for controls that have validation rules attached                 bool isValid = !Validation.GetHasError(node);                if (!isValid)                {                    // If the dependency object is invalid, and it can receive the focus,                    // set the focus                    if (node is IInputElement) Keyboard.Focus((IInputElement)node);                    return false;                }            }            // If this dependency object is valid, check all child dependency objects            foreach (object subnode in LogicalTreeHelper.GetChildren(node))            {                if (subnode is DependencyObject)                {                    // If a child dependency object is invalid, return false immediately,                    // otherwise keep checking                    if (IsValid((DependencyObject)subnode) == false) return false;                }            }            // All dependency objects are valid            return true;        }

    Click confirm to use this method for verification again. If the data is invalid, the user cannot submit

Code: Download

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.