validation规则使用来自另一个控件的值

我正在尝试做一些我之前认为非常简单的事情:在另一个控件的validation规则中使用一个控件的值。 我的应用程序具有用户可以输入的各种参数,这里讨论的特定参数定义范围的起点和终点,用户通过文本框设置值。

有问题的两个控件是开始和结束文本框,并且应在validation中检查以下条件:

  1. 起始值必须大于或等于某个任意值
  2. 结束值必须小于或等于某个任意值
  3. 起始值必须小于或等于结束值

我已经完成的前两个条件。 第三个实现起来要困难得多,因为我无法从validation器访问结束文本框的值。 即使我可以,有五个不同的范围(每个都有自己的开始和结束文本框)我正在尝试validation,并且必须有一些解决方案比为每个范围创建validation规则更优雅。

这是相关的XAML代码:

                         

这是相关的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; using System.Globalization; namespace WpfApplication1 { ///  /// Interaction logic for MainWindow.xaml ///  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  Max)) { return new ValidationResult(false, "Out of range. Enter a parameter in the range: " + Min + " - " + Max + "."); } else { return new ValidationResult(true, null); } } } } 

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

谢谢…

对于任何可能面临此问题的人来说,实现IDataErrorInfo以更正常地validation错误,并在某些逻辑分组中完成对其他控件的validation要容易得多。 我将相关属性(start,end,min和max)封装在一个类中,将控件绑定到这些属性,然后使用IDataErrorInfo接口进行validation。 相关代码如下……

XAML:

     

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 { ///  /// Interaction logic for MainWindow.xaml ///  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. //eg 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. //eg 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; } } } }