如何为 class 的 属性 生成错误
How to generate an error for a property of a class
我有一个具有 属性 的 ViewModel。
这个属性是一个"PhysicalValue"。这个 PhysicalValue 是由一个 Value 和一个 Unit 组成的 class。
public Class MyViewModel:INotifyPropertyChanged:IDataErrorInfo {
public PhysicalValue Target {get => _target; set => {_target = value; NotifyPropertyChanged("Target");}}
public string this[string columnName]
{
get
{
if (columnName == "Target")
{
if(_target.Value>5000){
return "out of spec value";
}
}
return String.Empty;
}
}
}
我有一个控件应该编辑此 PhysicalValue 的值:
[...]
<dxe:TextEdit EditValue="{Binding Target.Value, ValidatesOnDataErrors =true}"></dxe:TextEdit>
[...]
但我没有错误(可能是因为它搜索 Target.Value
有错误。我尝试了另一种方法,直接绑定到 Target
,但这不起作用,因为我需要 convertBack 来知道最初使用哪个 Unit 来重建 PhysicalValue。
你会如何解决这个问题?
您的 TextEdit 控件的 EditValue 属性 绑定到 PhysicalValue.Value
。当您将 Binding.ValidatesOnDataErrors
设置为 true 时,绑定引擎会检查具有目标 属性 的 class 是否实现了 IDataErrorInfo
。
所以为了这个工作 PhysicalValue
class 需要实施 IDataErrorInfo
:
class PhysicalValue : IDataErrorInfo
{
public double Value { get; set; }
public object Unit { get; set; }
public string Error => this["Value"] + this["Unit"];
public PhysicalValue(int v, object u)
{
Value = v;
Unit = u;
}
public string this[string columnName]
{
get
{
if (columnName == "Value")
{
if (Value > 5000)
{
return "out of spec value";
}
}
return String.Empty;
}
}
}
如果 PhysicalValue class 无法保存验证逻辑或无法实现 IDataErrorInfo
接口,您可以创建一个代理 class 来处理验证并绑定到该代理。这是一个小例子:
class PhysicalValueValidator : IDataErrorInfo
{
private readonly PhysicalValue _physicalValue;
private double _maxValue;
public double Value
{
get { return _physicalValue.Value; }
set { _physicalValue.Value = value; }
}
public PhysicalValueValidator(PhysicalValue pv)
{
_physicalValue = pv;
_maxValue = 5000;
}
public void SetMaxValue(double maxValue)
{
_maxValue = maxValue;
}
public string this[string columnName]
{
get
{
if (columnName == "Value")
{
if (Value > _maxValue)
{
return "out of spec value";
}
}
return String.Empty;
}
}
public string Error => this["Value"];
}
PhysicalValueValidator
class 公开了 SetMaxValue(..)
方法来更新窗格视图模型的验证逻辑。视图模型可能如下所示:
class MyViewModel
{
private PhysicalValue _target;
public PhysicalValueValidator TargetValidator { get; }
public MyViewModel()
{
_target = new PhysicalValue(5, 10);
TargetValidator = new PhysicalValueValidator(_target);
// update validation Logic...
TargetValidator.SetMaxValue(6000);
}
}
在您的 xaml 代码中,绑定到 TargetValidator.Value 而不是 Target.Value。
有关 IDataErrorInfo 的更多信息,请查看此 link:IDataErrorInfo
我有一个具有 属性 的 ViewModel。 这个属性是一个"PhysicalValue"。这个 PhysicalValue 是由一个 Value 和一个 Unit 组成的 class。
public Class MyViewModel:INotifyPropertyChanged:IDataErrorInfo {
public PhysicalValue Target {get => _target; set => {_target = value; NotifyPropertyChanged("Target");}}
public string this[string columnName]
{
get
{
if (columnName == "Target")
{
if(_target.Value>5000){
return "out of spec value";
}
}
return String.Empty;
}
}
}
我有一个控件应该编辑此 PhysicalValue 的值:
[...]
<dxe:TextEdit EditValue="{Binding Target.Value, ValidatesOnDataErrors =true}"></dxe:TextEdit>
[...]
但我没有错误(可能是因为它搜索 Target.Value
有错误。我尝试了另一种方法,直接绑定到 Target
,但这不起作用,因为我需要 convertBack 来知道最初使用哪个 Unit 来重建 PhysicalValue。
你会如何解决这个问题?
您的 TextEdit 控件的 EditValue 属性 绑定到 PhysicalValue.Value
。当您将 Binding.ValidatesOnDataErrors
设置为 true 时,绑定引擎会检查具有目标 属性 的 class 是否实现了 IDataErrorInfo
。
所以为了这个工作 PhysicalValue
class 需要实施 IDataErrorInfo
:
class PhysicalValue : IDataErrorInfo
{
public double Value { get; set; }
public object Unit { get; set; }
public string Error => this["Value"] + this["Unit"];
public PhysicalValue(int v, object u)
{
Value = v;
Unit = u;
}
public string this[string columnName]
{
get
{
if (columnName == "Value")
{
if (Value > 5000)
{
return "out of spec value";
}
}
return String.Empty;
}
}
}
如果 PhysicalValue class 无法保存验证逻辑或无法实现 IDataErrorInfo
接口,您可以创建一个代理 class 来处理验证并绑定到该代理。这是一个小例子:
class PhysicalValueValidator : IDataErrorInfo
{
private readonly PhysicalValue _physicalValue;
private double _maxValue;
public double Value
{
get { return _physicalValue.Value; }
set { _physicalValue.Value = value; }
}
public PhysicalValueValidator(PhysicalValue pv)
{
_physicalValue = pv;
_maxValue = 5000;
}
public void SetMaxValue(double maxValue)
{
_maxValue = maxValue;
}
public string this[string columnName]
{
get
{
if (columnName == "Value")
{
if (Value > _maxValue)
{
return "out of spec value";
}
}
return String.Empty;
}
}
public string Error => this["Value"];
}
PhysicalValueValidator
class 公开了 SetMaxValue(..)
方法来更新窗格视图模型的验证逻辑。视图模型可能如下所示:
class MyViewModel
{
private PhysicalValue _target;
public PhysicalValueValidator TargetValidator { get; }
public MyViewModel()
{
_target = new PhysicalValue(5, 10);
TargetValidator = new PhysicalValueValidator(_target);
// update validation Logic...
TargetValidator.SetMaxValue(6000);
}
}
在您的 xaml 代码中,绑定到 TargetValidator.Value 而不是 Target.Value。
有关 IDataErrorInfo 的更多信息,请查看此 link:IDataErrorInfo