[英]Validation rules using value from another control
我正在嘗試做一些我之前認為很容易的事情:在另一個控件的驗證規則中使用一個控件的值。 我的應用程序具有用戶可以輸入的各種參數,這里討論的特定參數定義范圍的起點和終點,用戶通過文本框設置值。
有問題的兩個控件是開始和結束文本框,並且應在驗證中檢查以下條件:
我已經完成的前兩個條件。 第三個實現起來要困難得多,因為我無法從驗證器訪問結束文本框的值。 即使我可以,有五個不同的范圍(每個都有自己的開始和結束文本框)我正在嘗試驗證,並且必須有一些解決方案比為每個范圍創建驗證規則更優雅。
這是相關的XAML代碼:
<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>
這是相關的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 {
/// <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);
}
}
}
}
這里鏈接的問題似乎是相關的,但我無法理解所提供的答案。
謝謝...
對於任何可能面臨此問題的人來說,實現IDataErrorInfo以更正常地驗證錯誤,並在某些邏輯分組中完成對其他控件的驗證要容易得多。 我將相關屬性(start,end,min和max)封裝在一個類中,將控件綁定到這些屬性,然后使用IDataErrorInfo接口進行驗證。 相關代碼如下......
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;
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.