【发布时间】:2011-10-31 10:15:25
【问题描述】:
我试图了解当它的 ItemsSource 绑定到复杂类型的 ObserableCollection 时,组合框的验证是如何工作的。我使用 RIA 作为将客户端层连接到中间层的服务。也不确定这是否会有所不同,组合框控件位于数据表单内。我对此进行了大量阅读,发现这篇文章是最有用的:http://www.run80.net/?p=93
首先我的实体:我有一个这样装饰的字段:
[Required]
public virtual long FrequencyId { get; set; }
[Include]
[Association("TreatmentFrequencyToTreatmentRecordAssociation", "FrequencyId", "Id", IsForeignKey = true)]
public virtual TreatmentFrequency Frequency
{
get
{
return this.frequency;
}
set
{
this.frequency = value;
if (value != null)
{
this.FrequencyId = value.Id;
}
}
}
现在我相信我不能在关联上设置 [Required] 注释,而是在外键 id 上设置(上面文章所说的)。
实际的治疗频率类如下所示:
public class TreatmentFrequency
{
[Key]
public virtual long Id { get; set; }
[Required]
[StringLength(10)]
public virtual string Code { get; set; }
[Required]
[StringLength(40)]
public virtual string Name { get; set; }
public override bool Equals(object obj)
{
obj = obj as TreatmentFrequency;
if (obj == null)
{
return false;
}
return this.Id == ((TreatmentFrequency)obj).Id;
}
public override int GetHashCode()
{
return this.Name.GetHashCode();
}
}
我已经重写了 Equals 和 GetHashCode 方法,因为在另一篇文章中它说,当在集合中时,您需要重写 equals 以匹配键,否则当您使用 SelectedItem 时,尽管项目之间的所有值都相同集合和选定项它们将是两个不同的实例,因此与 Equals 的默认实现不匹配。
现在我的 xaml 看起来像这样:
<df:DataField Label="Frequency">
<ComboBox SelectedItem="{Binding Path=CurrentItem.Frequency, Mode=TwoWay}" ItemsSource="{Binding Path=Frequencies}" DisplayMemberPath="Name" SelectedValue="{Binding Path=CurrentItem.FrequencyId, Mode=TwoWay}" SelectedValuePath="Id"/>
</df:DataField>
老实说,上述内容对我来说没有多大意义,我可以删除 SelectedValue 和 SelectedValuePath 并且表单仍然可以按预期工作(无需验证)我认为 Selected Value 将指向复杂类型,例如CurrentItem.Frequency 然后 SelectedValuePath 将是基础的“名称”属性。但是,我也理解作者试图做什么,因为 [Required] 标签不在关联上,而是在外键 id 上,例如CurrentItem.FrequencyId,所以它必须去某个地方。
现在最后的复杂性是此表单是向导的一部分,因此我无法验证整个对象,而是必须手动验证仅在此特定向导步骤中填充的某些字段。为此,我创建了方法:
public void ValidateProperty(object value, string propertyName)
{
var results = new List<ValidationResult>();
Validator.TryValidateProperty(value, new ValidationContext(this.TreatmentRecord, null, null) { MemberName = propertyName }, results);
foreach (var error in results)
{
this.TreatmentRecord.ValidationErrors.Add(error);
}
}
在我的视图模型中,我有一个 IsValid 方法,在允许向导导航到下一步之前调用它,然后我像这样调用上述方法:
public bool IsValid
{
get
{
this.treatmentRecordWizardContext.ValidateProperty(this.treatmentRecordWizardContext.TreatmentRecord.Frequency, "Frequency");
this.treatmentRecordWizardContext.ValidateProperty(this.treatmentRecordWizardContext.TreatmentRecord.FrequencyId, "FrequencyId");
this.OnPropertyChanged(() => this.CurrentItem);
if (this.treatmentRecordWizardContext.TreatmentRecord.ValidationErrors.Count == 0)
{
return true;
}
return false;
}
}
使用上述所有代码,当组合框为空时,验证将被完全忽略。我没有对组合框本身进行模板化,所以我真的不知道为什么它不工作以及解决方案的哪一部分有问题,是绑定还是 RIA 中的实体定义不正确!
希望有人可以帮助我花了很长时间试图让它工作,我认为这必须由其他开发人员定期完成,所以我希望它是一个简单的修复。
【问题讨论】:
-
我不确定验证是否适用于
CurrentItem.Frequency这样的链绑定。另外我会使用带有INotifyDataErrorInfo接口的 mvvm 方法而不是数据注释,因为它更灵活。
标签: silverlight validation mvvm