Я пытаюсь понять, как работает проверка для поля со списком, когда его ItemsSource связан с ObserableCollection сложных типов.Я использую RIA в качестве службы для подключения уровня клиента к среднему уровню.Также не уверен, если это имеет значение, элемент управления combobox находится внутри формы данных.Я много читал об этом и нашел эту статью наиболее полезной: 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;
}
}
}
СейчасЯ верю, что я не могу установить аннотацию [Обязательный] для ассоциации, но вместо этого для идентификатора внешнего ключа (о чем говорится в вышеприведенной статье).
Фактический класс частоты обработки выглядит следующим образом:
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, хотя все значения будут одинаковыми для элемента вколлекция и 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 и форма будет по-прежнему работать как expЯ думал, что Selected Value будет указывать на сложный тип, например CurrentItem.Frequency, и тогда SelectedValuePath будет лежать в основе свойства «Name».Однако я также понимаю, что автор пытается сделать в том, что тег [Обязательный] не связан с ассоциацией, а имеет идентификатор внешнего ключа, например 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 не определены правильно!
Надеюсь, кто-то может помочь. Я потратил слишком много времени, пытаясь заставить это работать, я полагаю, что это должны делать другие разработчики регулярно, поэтому я надеюсь, что это простое исправление.