wpf - WPF 使用 IDataErrorInfo 验证子类属性
问题描述
给定下一个示例:
模型
public class ProjecteModel : ObservableObject, IProjecteModel
{
private string _patientID
public string IdPacient
{
get => _idPacient;
set
{
_idPacient = value;
OnPropertyChanged(nameof(IdPacient));
}
}
/* More fields here... */
}
其中 ObservableObject 是实现 INotifyPropertyChanged 接口的基类。
视图模型
public class ProjecteViewModel : BaseViewModel, IDataErrorInfo
{
private IProjecteModel _projecte = new ProjecteModel();
private string _codiClient;
public IProjecteModel Projecte
{
get => _projecte;
set
{
_projecte = value;
OnPropertyChanged(nameof(Projecte));
}
}
public string CodiClient
{
get => _codiClient;
set
{
_codiClient = value;
OnPropertyChanged(nameof(CodiClient));
}
}
public string this[string columnName]
{
get
{
string msg = String.Empty;
switch (columnName)
{
case "CodiClient":
if (CodiClient.Length <= 0)
{
msg = "ID Client is required.";
}
break;
case "IdPacient":
//case "Projecte.IdPacient":
if (Projecte.IdPacient.Length <= 0)
{
msg = "Id Pacient is required.";
}
break;
};
return msg;
}
}
}
看法
<!-- Id Pacient -->
<StackPanel Orientation="Vertical"
Width="{Binding ElementName=capComandes, Path=ItemsWidth}">
<TextBlock Text="ID Pacient:"
Style="{StaticResource FieldNameTextBlock}"/>
<TextBox x:Name="IdPacient"
Width="150"
HorizontalAlignment="Left"
Margin="0, 0, 0, 15"
Foreground="{StaticResource ForegroundFieldValuesBrush}"
Text="{Binding Projecte.IdPacient,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}"/>
</StackPanel>
<!-- CodiClient -->
<StackPanel Orientation="Vertical"
Width="{Binding ElementName=capComandes, Path=ItemsWidth}">
<TextBlock Text="ID Client:"
Style="{StaticResource FieldNameTextBlock}"/>
<TextBox x:Name="IdClient"
Width="150"
HorizontalAlignment="Left"
Foreground="{StaticResource ForegroundFieldValuesBrush}"
Text="{Binding CodiClient,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged,
ValidatesOnDataErrors=True}">
</TextBox>
</StackPanel>
验证适用于 CodiClient,但不适用于 IdPacient。
验证方法:public string this[string columnName]
从不为 IdPacient 调用。
如何验证子类属性?
解决方案
IDataErrorInfo
需要在包含您绑定到的属性的任何类中实现。
看看我的博客文章,我的基础可绑定对象类实现了 IDataErrorInfo,并包含一个从属性ValidatePropety()
调用的虚拟方法。public string this[string columnName] {}
然后根据需要在每个后代类中覆盖它,以对特定属性执行实际验证。
public class perObservableObject: ObservableObject, IDataErrorInfo
{
private HashSet<string> InvalidProperties { get; } = new HashSet<string>();
public virtual bool IsValid => !InvalidProperties.Any();
public bool HasError(string propertyName) => InvalidProperties.Contains(propertyName);
protected virtual string ValidateProperty(string propertyName) => string.Empty;
public string this[string columnName]
{
get
{
if (nameof(IsValid).Equals(columnName))
return string.Empty;
var result = ValidateProperty(columnName);
var errorStateChanged = string.IsNullOrWhiteSpace(result)
? InvalidProperties.Remove(columnName)
: InvalidProperties.Add(columnName);
if (errorStateChanged)
RaisePropertyChanged(nameof(IsValid));
return result;
}
}
// IDataErrorInfo - redundant in WPF
public string Error => string.Empty;
}
[ObservableObject 来自 MvvmLight]
推荐阅读
- javascript - 如何在 ReactJS 中维护我的道具/状态?
- reactjs - 如何访问组件之外的历史对象(使用 HashRouter)?
- docker - 使用 Lando 从 PHPStorm 执行 PHPUnit 测试用例
- c# - 等到模态框被定位
- python - 如何在python中获取与列的n个最小值对应的日期时间索引
- regex - 如何从 {} 中提取单词并打印到新行
- python - 统一和自己的分布(Python)
- r - 用于分组过滤值的R代码
- c - 如何在不使用库的情况下让 MSP430 代码工作?
- powershell - 带有嵌入式 exe 的 Powershell 脚本