MVVM 模式:如果我们将模型包装在另一个模型中,则 IDataErrorInfo 验证不起作用
MVVM pattern: IDataErrorInfo validation doesn't work if we have wrapped model inside another model
问题是 UI 上没有显示红色矩形。
我使用 Caliburn.Micro,这就是我的 View:
<StackPanel Grid.Row="0">
<Label>Customer name:</Label>
<TextBox x:Name="txtName" Text="{Binding Target.Model.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="136" HorizontalAlignment="Left"/>
</StackPanel>
这里是 ViewModel:
internal class ShellViewModel : Screen
{
private EditableCustomer _Target;
public EditableCustomer Target
{
get { return _Target; }
set { if (_Target != value) { _Target = value; NotifyOfPropertyChange(nameof(Target)); } }
}
}
这是我在模型中的内容:
internal class EditableCustomer : PropertyChangedBase, IDataErrorInfo
{
private CustomerInfo _Model;
public CustomerInfo Model
{
get { return _Model; }
set { if (_Model != value) { _Model = value; NotifyOfPropertyChange(nameof(Model)); } }
}
}
这是另一个 型号:
internal class CustomerInfo : PropertyChangedBase
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; NotifyOfPropertyChange(nameof(Name)); }
}
}
我知道我可以将 IDataErrorInfo 接口从 EditableCustomer 移动到 CustomerInfo 模型,如果我这样做,一切都会完美地工作,但问题是我不允许在 CustomerInfo 模型中进行任何更改,
有人知道我还能做什么吗?
Does anybody have any idea what else I can do?
由于数据绑定 属性 的 class 应该实现 IDataErrorInfo 接口,因此您需要绑定到 EditableCustomer class 的 属性包装 CustomerInfo 模型的名称 属性:
<TextBox x:Name="txtName" Text="{Binding Target.NameWrapper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="136" HorizontalAlignment="Left"/>
internal class EditableCustomer : PropertyChangedBase, IDataErrorInfo
{
private CustomerInfo _Model;
public CustomerInfo Model
{
get { return _Model; }
set { if (_Model != value) { _Model = value; NotifyOfPropertyChange(nameof(Model)); } }
}
//bind to this one instead of binding directly to the Name property of the model:
public string NameWrapper
{
get { return _Model.Name; }
set { _Model.Name = value; NotifyOfPropertyChange(nameof(NameWrapper)); }
}
}
您要么必须这样做,要么让 CustomerInfo class 实现 IDataErrorInfo 接口。挑挑拣拣。
在 xaml 中使用 Fluid Validations 会很容易。
public class ModelValidator : AbstractValidator<Customer>
{
public ModelValidator(){
RuleFor(model => model.Name).NotEmpty().WithMessage("Name is Requried");
RuleFor(model => model.Age).NotEmpty().WithMessage("Age is Required");
RuleFor(model => model.Designation).NotEmpty().WithMessage("Choose Your Designation");
}
}
这将有助于在 wpf 中进行验证。
一旦你提到了 fluidValidations。
问题是 UI 上没有显示红色矩形。
我使用 Caliburn.Micro,这就是我的 View:
<StackPanel Grid.Row="0">
<Label>Customer name:</Label>
<TextBox x:Name="txtName" Text="{Binding Target.Model.Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="136" HorizontalAlignment="Left"/>
</StackPanel>
这里是 ViewModel:
internal class ShellViewModel : Screen
{
private EditableCustomer _Target;
public EditableCustomer Target
{
get { return _Target; }
set { if (_Target != value) { _Target = value; NotifyOfPropertyChange(nameof(Target)); } }
}
}
这是我在模型中的内容:
internal class EditableCustomer : PropertyChangedBase, IDataErrorInfo
{
private CustomerInfo _Model;
public CustomerInfo Model
{
get { return _Model; }
set { if (_Model != value) { _Model = value; NotifyOfPropertyChange(nameof(Model)); } }
}
}
这是另一个 型号:
internal class CustomerInfo : PropertyChangedBase
{
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; NotifyOfPropertyChange(nameof(Name)); }
}
}
我知道我可以将 IDataErrorInfo 接口从 EditableCustomer 移动到 CustomerInfo 模型,如果我这样做,一切都会完美地工作,但问题是我不允许在 CustomerInfo 模型中进行任何更改,
有人知道我还能做什么吗?
Does anybody have any idea what else I can do?
由于数据绑定 属性 的 class 应该实现 IDataErrorInfo 接口,因此您需要绑定到 EditableCustomer class 的 属性包装 CustomerInfo 模型的名称 属性:
<TextBox x:Name="txtName" Text="{Binding Target.NameWrapper, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" Width="136" HorizontalAlignment="Left"/>
internal class EditableCustomer : PropertyChangedBase, IDataErrorInfo
{
private CustomerInfo _Model;
public CustomerInfo Model
{
get { return _Model; }
set { if (_Model != value) { _Model = value; NotifyOfPropertyChange(nameof(Model)); } }
}
//bind to this one instead of binding directly to the Name property of the model:
public string NameWrapper
{
get { return _Model.Name; }
set { _Model.Name = value; NotifyOfPropertyChange(nameof(NameWrapper)); }
}
}
您要么必须这样做,要么让 CustomerInfo class 实现 IDataErrorInfo 接口。挑挑拣拣。
在 xaml 中使用 Fluid Validations 会很容易。
public class ModelValidator : AbstractValidator<Customer>
{
public ModelValidator(){
RuleFor(model => model.Name).NotEmpty().WithMessage("Name is Requried");
RuleFor(model => model.Age).NotEmpty().WithMessage("Age is Required");
RuleFor(model => model.Designation).NotEmpty().WithMessage("Choose Your Designation");
}
}
这将有助于在 wpf 中进行验证。
一旦你提到了 fluidValidations。