使用另一控制值的验证规则 [英] Validation rules using value from another control

查看:101
本文介绍了使用另一控制值的验证规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一些事情,我以前承担将相当简单:从别人的验证规则一个控制使用的值。我的应用程序有多种参数,用户可以输入,所讨论的具体参数此处定义的范围的起点和终点,和用户通过文本框设定值



所讨论的两个控制是开始和结束文本框,并在下列条件应该在验证检查:



<醇>
  • 开始值必须大于或等于某一任意值

  • 结束值必须小于或等于某个任意值

  • 开始值必须小于或等于结束值



  • 前两个条件,我已经完成。三是实施更加困难,因为我不能从验证访问结束文本框的值。就算我想到了,有五个不同的范围(每个都有自己开始和结束的文本框),我试图验证,并且必须有一些解决方案,比创建为每一个验证规则更加优雅。



    下面是相关XAML代码:

     <窗​​口x:类=WpfApplication1。主窗口
    的xmlns =http://schemas.microsoft.com/winfx/2006/xaml/presentation
    的xmlns:X =http://schemas.microsoft.com/winfx/2006/ XAML
    的xmlns:验证=CLR的命名空间:CustomValidators
    标题=主窗口HEIGHT =350WIDTH =525>
    <网格和GT;
    < Grid.RowDefinitions>
    < RowDefinition />
    < RowDefinition />
    < /Grid.RowDefinitions>

    <文本框名称=textboxStartGrid.Row =0>
    < TextBox.Text>
    <绑定路径=开始UpdateSourceTrigger =的PropertyChanged>
    < Binding.ValidationRules>
    <验证:MeasurementRangeRule最小=1513最大=1583/>
    < /Binding.ValidationRules>
    < /绑定>
    < /TextBox.Text>
    < /文本框>

    <文本框名称=textboxEndGrid.Row =1>
    < TextBox.Text>
    <绑定路径=结束UpdateSourceTrigger =的PropertyChanged>
    < Binding.ValidationRules>
    <验证:MeasurementRangeRule最小=1513最大=1583/>
    < /Binding.ValidationRules>
    < /绑定>
    < /TextBox.Text>
    < /文本框>
    < /网格和GT;





    和这里是有关C#代码:

     使用系统; 
    使用System.Collections.Generic;
    使用System.Linq的;
    使用System.Text;使用System.Threading.Tasks
    ;使用System.Windows
    ;使用System.Windows.Controls的
    ;
    使用System.Windows.Data;使用System.Windows.Documents
    ;
    使用System.Windows.Input;使用System.Windows.Media
    ;
    使用System.Windows.Media.Imaging;
    使用System.Windows.Navigation;使用System.Windows.Shapes
    ;使用System.Runtime.CompilerServices
    ;
    使用System.ComponentModel;
    使用System.Globalization;

    命名空间WpfApplication1 {
    ///<总结> $ B $为MainWindow.xaml
    ///< b ///交互逻辑; /总结>
    公共部分类主窗口:窗口{
    公共主窗口(){
    的InitializeComponent();
    }

    私人小数_start;
    私人小数_end;
    公共事件PropertyChangedEventHandler的PropertyChanged;

    公共小数开始{
    {返回_start; }
    集合{
    _start =价值;
    RaisePropertyChanged();
    }
    }

    公共小数尾{
    {返回_end; }
    集合{
    _end =价值;
    RaisePropertyChanged();
    }
    }

    私人无效RaisePropertyChanged([CallerMemberName]字符串参数propertyName =){
    如果(的PropertyChanged!= NULL){
    的PropertyChanged(对此,新PropertyChangedEventArgs(propertyName的));
    }
    }
    }
    }

    命名空间CustomValidators {

    公共类MeasurementRangeRule:有效性规则{
    私人十进制_min;
    私人小数_MAX;

    公共小数民{
    {返回_min; }
    集合{_min =价值; }
    }

    公共十进制最大{
    {返回_MAX; }
    集合{_MAX =价值; }
    }

    公众覆盖的ValidationResult验证(对象的值,CultureInfo的CultureInfo的){
    十进制measurementParameter = 0;

    尝试{
    如果(((串)值)。长度大于0)
    measurementParameter = Decimal.Parse((字符串)值);
    }赶上(例外五){
    返回新的ValidationResult(假,非法字符或+ e.Message);
    }

    如果((measurementParameter<最小值)||(measurementParameter>最大)){
    返回新的ValidationResult(假,
    超出范围。 ,输入该范围的参数:+敏+ - + MAX +);
    }其他{
    返回新的ValidationResult(TRUE,NULL);
    }
    }
    }
    }



    问题挂钩这里似乎是相关的,但我无法理解提供的答案。



    谢谢...


    解决方案

    对于任何谁可能面对这个问题,这是更容易实现IDataErrorInfo的验证一般的错误,并实现与其他控件的有效性在一些逻辑分组。我在一个类封装相关属性(开始,结束,最小值和最大值),绑定的控件的属性,然后用于验证的IDataErrorInfo的接口。相关代码如下...



    XAML:





     <文本框名称=textboxStartGrid.Row =0文本={绑定路径=开始,ValidatesOnDataErrors = TRUE} 保证金=10/> 
    <文本框名称=textboxEndGrid.Row =1文本={绑定路径=结束,ValidatesOnDataErrors = TRUE}保证金=10/>
    < /网格和GT;





    C#:



     使用系统; 
    使用System.Collections.Generic;
    使用System.Linq的;
    使用System.Text;使用System.Threading.Tasks
    ;使用System.Windows
    ;使用System.Windows.Controls的
    ;
    使用System.Windows.Data;使用System.Windows.Documents
    ;
    使用System.Windows.Input;使用System.Windows.Media
    ;
    使用System.Windows.Media.Imaging;
    使用System.Windows.Navigation;使用System.Windows.Shapes
    ;使用System.Runtime.CompilerServices
    ;
    使用System.ComponentModel;

    命名空间WpfApplication1 {
    ///<总结> $ B $为MainWindow.xaml
    ///< b ///交互逻辑; /总结>
    公共部分类主窗口:窗口{
    公共主窗口(){
    的InitializeComponent();

    参数= testParameter新参数(0,10);
    testGrid.DataContext = testParameter;
    }
    }

    公共类参数:INotifyPropertyChanged的,IDataErrorInfo的{
    私人小数_start,_end,_min,_MAX;
    公共事件PropertyChangedEventHandler的PropertyChanged;

    公共参数(){}

    公共参数(十进制分钟,十进制最大){
    this.Min =分钟;
    this.Max =最大值;
    }

    公共小数开始{
    {返回_start; }
    集合{
    _start =价值;
    // RaisePropertyChanged为开始和结束,因为人们可能需要被标记,因为对方的当前设置为无效。
    //e.g。开始>端,在这种情况下,两个特性是目前无效,根据所建立的条件,但只有最近更改属性将被验证
    RaisePropertyChanged();
    RaisePropertyChanged(结束);
    }
    }

    公共小数尾{
    {返回_end; }
    集合{
    _end =价值;
    // RaisePropertyChanged为开始和结束,因为人们可能需要被标记,因为对方的当前设置为无效。
    //e.g。开始>端,在这种情况下,两个特性是目前无效,根据所建立的条件,但只有最近更改属性将被验证
    RaisePropertyChanged();
    RaisePropertyChanged(开始);
    }
    }

    公共小数民{
    {返回_min; }
    集合{_min =价值; }
    }

    公共十进制最大{
    {返回_MAX; }
    集合{_MAX =价值; }
    }

    私人无效RaisePropertyChanged([CallerMemberName]字符串参数propertyName =){
    如果(的PropertyChanged!= NULL){
    的PropertyChanged(这一点,新PropertyChangedEventArgs (propertyName的));
    }
    }

    公共字符串错误{
    {返回的String.Empty; }
    }

    公共字符串此[字符串COLUMNNAME] {
    获得{
    字符串结果=的String.Empty;

    开关(COLUMNNAME){
    案开始:
    如果(开始<最低||开始>最大||开始>完){
    结果=超出范围输入范围内的值。 - +敏++ +端;
    }
    中断;
    案结束:
    如果(完<最低||尾>最大||尾<开始){
    结果=超出范围的范围内输入一个值。 :+ START + - + MAX +;。
    }
    中断;
    };

    返回结果;
    }
    }
    }
    }


    I'm trying to do something that I previously assumed would be quite easy: use the value from one control in the validation rule of another. My application has a variety of parameters that the user can enter, the specific parameters in question here define the start and end points of a range, and the user sets the values through a textbox.

    The two controls in question are the start and end textboxes, and the following conditions should be checked in validation:

    1. Start value must be greater than or equal to some arbitrary value
    2. End value must be less than or equal to some arbitrary value
    3. Start value must be less than or equal to end value

    The first two conditions I have already accomplished. The third is far more difficult to implement, because I cannot access the end textbox's value from the validator. Even if I could, there are five different ranges (each with their own start and end textbox) I'm trying to validate, and there must be some solution more elegant than creating a validation rule for each one.

    Here is the relevant XAML code:

    <Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:validators="clr-namespace:CustomValidators"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
    
        <TextBox Name="textboxStart" Grid.Row="0">
            <TextBox.Text>
                <Binding Path="Start" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <validators:MeasurementRangeRule Min="1513" Max="1583"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    
        <TextBox Name="textboxEnd" Grid.Row="1">
            <TextBox.Text>
                <Binding Path="End" UpdateSourceTrigger="PropertyChanged">
                    <Binding.ValidationRules>
                        <validators:MeasurementRangeRule Min="1513" Max="1583"/>
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
    </Grid>
    

    And here is the relevant C# code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Runtime.CompilerServices;
    using System.ComponentModel;
    using System.Globalization;
    
    namespace WpfApplication1 {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window {
            public MainWindow () {
                InitializeComponent();
            }
    
            private decimal _start;
            private decimal _end;
            public event PropertyChangedEventHandler PropertyChanged;
    
            public decimal Start {
                get { return _start; }
                set {
                    _start = value;
                    RaisePropertyChanged();
                }
            }
    
            public decimal End {
                get { return _end; }
                set {
                    _end = value;
                    RaisePropertyChanged();
                }
            }
    
            private void RaisePropertyChanged ([CallerMemberName] string propertyName = "") {
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    }
    
    namespace CustomValidators {
    
        public class MeasurementRangeRule : ValidationRule {
            private decimal _min;
            private decimal _max;
    
            public decimal Min {
                get { return _min; }
                set { _min = value; }
            }
    
            public decimal Max {
                get { return _max; }
                set { _max = value; }
            }
    
            public override ValidationResult Validate (object value, CultureInfo cultureInfo) {
                decimal measurementParameter = 0;
    
                try {
                    if (((string) value).Length > 0)
                        measurementParameter = Decimal.Parse((String) value);
                } catch (Exception e) {
                    return new ValidationResult(false, "Illegal characters or " + e.Message);
                }
    
                if ((measurementParameter < Min) || (measurementParameter > Max)) {
                    return new ValidationResult(false,
                      "Out of range. Enter a parameter in the range: " + Min + " - " + Max + ".");
                } else {
                    return new ValidationResult(true, null);
                }
            }
        }
    }
    

    The question linked here seems to be relevant, but I cannot understand the answers provided.

    Thanks...

    解决方案

    For any who might face this problem, it is far easier to implement IDataErrorInfo to validate errors in general, and to accomplish validation against other controls in some logical grouping. I encapsulated the relevant properties (start, end, min and max) in a single class, bound the controls to those properties, and then used the IDataErrorInfo interface for validation. Relevant code is below...

    XAML:

        <TextBox Name="textboxStart" Grid.Row="0" Text="{Binding Path=Start, ValidatesOnDataErrors=True}" Margin="5"/>
        <TextBox Name="textboxEnd" Grid.Row="1" Text="{Binding Path=End, ValidatesOnDataErrors=True}" Margin="5"/>
    </Grid>
    

    C#:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Runtime.CompilerServices;
    using System.ComponentModel;
    
    namespace WpfApplication1 {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window {
            public MainWindow () {
                InitializeComponent();
    
                Parameter testParameter = new Parameter(0, 10);
                testGrid.DataContext = testParameter;
            }
        }
    
        public class Parameter: INotifyPropertyChanged, IDataErrorInfo {
            private decimal _start, _end, _min, _max;
            public event PropertyChangedEventHandler PropertyChanged;
    
            public Parameter () { }
    
            public Parameter (decimal min, decimal max) {
                this.Min = min;
                this.Max = max;
            }
    
            public decimal Start {
                get { return _start; }
                set {
                    _start = value;
                    //RaisePropertyChanged for both Start and End, because one may need to be marked as invalid because of the other's current setting.
                    //e.g. Start > End, in which case both properties are now invalid according to the established conditions, but only the most recently changed property will be validated
                    RaisePropertyChanged();
                    RaisePropertyChanged("End");
                }
            }
    
            public decimal End {
                get { return _end; }
                set {
                    _end = value;
                    //RaisePropertyChanged for both Start and End, because one may need to be marked as invalid because of the other's current setting.
                    //e.g. Start > End, in which case both properties are now invalid according to the established conditions, but only the most recently changed property will be validated
                    RaisePropertyChanged();
                    RaisePropertyChanged("Start");
                }
            }
    
            public decimal Min {
                get { return _min; }
                set { _min = value; }
            }
    
            public decimal Max {
                get { return _max; }
                set { _max = value; }
            }
    
            private void RaisePropertyChanged ([CallerMemberName] string propertyName = "") {
                if (PropertyChanged != null) {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            public string Error {
                get { return string.Empty; }
            }
    
            public string this[string columnName] {
                get {
                    string result = string.Empty;
    
                    switch (columnName) {
                        case "Start":
                            if (Start < Min || Start > Max || Start > End) {
                                result = "Out of range. Enter a value in the range: " + Min + " - " + End + ".";
                            }
                            break;
                        case "End":
                            if (End < Min || End > Max || End < Start) {
                                result = "Out of range. Enter a value in the range: " + Start + " - " + Max + ".";
                            }
                            break;
                    };
    
                    return result;
                }
            }
        }
    }
    

    这篇关于使用另一控制值的验证规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆