我有一个类DataModel
,它有一堆对象,它们都是同一个类InputItem
。 InputItem
类有一个可为空的十进制属性Value
,我要在DataModel
类中验证({{>} 在InputItem
类中) 。这是因为一个InputItem
对象的验证取决于另一个 InputItem
对象中的值。我希望IDataErrorInfo
用于此目的,但尚未能使其正常工作(此代码允许我绑定InputItem
中的值,但不会# 39;执行任何验证。
我的DataModel类:
using System.ComponentModel;
public class DataModel : IDataErrorInfo
{
public InputItem Item1 {get; set;}
public InputItem Item2 {get; set;}
public InputItem Item3 {get; set;}
//... more InputItem objects
public string Error { get { return string.Empty;} }
public string this[string propertyName]
{
get
{
string result = string.Empty;
switch (propertyName)
{
case "Item1":
case "Item1.Value":
if (Item1.Value == null)
result = "Item 1 is required.";
else if (Item1.Value < 0)
result = "Item 1 must be greater than 0.";
break;
case "Item2":
case "Item2.Value":
if (Item2.Value == null)
result = "Item 2 is required.";
else if (Item2.Value < Item1.Value)
result = "Item 2 must be greater than item 1";
break;
case "Item3":
case "Item3.Value":
if (Item3.Value == null)
result = empty.String;
else if (Item3.Value < Item1.Value)
result = "Item 3 must be greater than Item 1."
else if (Item3.Value > Item2.Value)
result = "Item 3 must be less than Item 2."
}
return result;
}
}
}
public class InputItem : INotifyPropertyChanged
{
//Implements INotifyPropertyChanged, but I'm leaving it out to shorten the code
public string Name {get; set;}
public decimal? Value {get; set;}
public string Unit {get; set;}
public string Tip { get; set; }
//... more properties
// ... Standard constructors
}
最终,我想将XAML视图中某些TextBox
个对象的某些属性绑定到不同InputItem
个对象中的属性,就像这样(使用视图&#39; s {{ 1}}设置为DataContext
对象):
DataModel
以前,我尝试为每个具有最小和最大允许值的InputItem对象设置验证规则,然后将验证规则中的最小值和最大值绑定到其他InputItem对象中的值,但是您可以从我的描述,这变得复杂和快速纠结。
以下是我用于<TextBox Text="{Binding Path=Item1.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"/>
和绑定策略的代码,以防您感兴趣:
ValidationRule
我已经查看了How to validate child objects by implementing IDataErrorInfo on parent class,但它并不适用于这种情况(该人真的想要自己验证各个子对象,而不是通过父对象)。 / p>
我还查看了this post by Brian Lagunas,但它也不适用,因为每个using System.Globalization;
using System.Windows;
using System.Windows.Controls;
public class NumberValidationRuleWithWrapper : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
decimal result = 0;
bool canConvert = decimal.TryParse(value as string, out result);
if (!canConvert)
return new ValidationResult(false, "Must be a valid number");
decimal? maxval = this.Wrapper.MaxValue;
if (maxval != null && !double.IsNaN((double)maxval))
{
if (result >= maxval)
return new ValidationResult(false, "Must be less than " + ((decimal)maxval).ToString());
}
decimal? minVal = this.Wrapper.MinValue;
if (minVal != null && !double.IsNaN((double)minVal))
{
if (result <= minVal)
return new ValidationResult(false, "Must be greater than " + ((decimal)minVal).ToString());
}
return ValidationResult.ValidResult;
}
public DecimalWrapper Wrapper { get; set; }
}
public class DecimalWrapper : DependencyObject
{
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue",
typeof(double?),
typeof(DecimalWrapper),
new FrameworkPropertyMetadata(double.MaxValue));
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue",
typeof(double?),
typeof(DecimalWrapper),
new FrameworkPropertyMetadata(double.MinValue));
public decimal? MaxValue
{
get { return (decimal?)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}
public decimal? MinValue
{
get { return (decimal?)GetValue(MinValueProperty); }
set { SetValue(MinValueProperty, value); }
}
}
对象都有与其他InputItem
对象相关的不同规则(例如Item1 can是任何数字,Item2必须小于Item1,Item3必须在Item1和Item2之间,Item4必须大于Item3,等等。
答案 0 :(得分:1)
绑定到Item1.Value
时,只有IDataErrorInfo
属性所属类型的Value
实现,即InputItem
才重要。 DataModel
是否实现IDataErrorInfo
无关紧要。
.NET Framework 4.5中嵌入的INotifyDataErrorInfo接口使WPF数据验证更加灵活。
如果要在DataModel
类中执行验证,可以在InputItem
类中实现此接口,并设置从GetErrors
方法返回的实际错误并引发{来自ErrorsChanged
类的{1}}事件。有一个如何实现此处可用界面的示例:https://social.technet.microsoft.com/wiki/contents/articles/19490.wpf-4-5-validating-data-in-using-the-inotifydataerrorinfo-interface.aspx。