Валидация комбинированного списка в Silverlight 4 - PullRequest
0 голосов
/ 31 октября 2011

Я пытаюсь понять, как работает проверка для поля со списком, когда его 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 не определены правильно!

Надеюсь, кто-то может помочь. Я потратил слишком много времени, пытаясь заставить это работать, я полагаю, что это должны делать другие разработчики регулярно, поэтому я надеюсь, что это простое исправление.

1 Ответ

0 голосов
/ 02 ноября 2011

На самом деле это была простая проблема, я предположил, что аннотация [Обязательный] проверит наличие ассоциации, а не ноль. Кажется, что все, что он на самом деле делает, это проверяет, что в этом случае FrequencyId не равен нулю. И была проблема в том, что я использовал long, а не nullable long (long?). Как только я внес изменения, чтобы сделать их обнуляемыми, проверка начала работать, как и ожидалось, даже с привязками, которые для меня не имели смысла. Если бы кто-нибудь мог объяснить им, это было бы здорово!

Phil

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...