2013-07-23 3 views
7

У меня есть приложение, которое использует шаблон MVVM, и я хотел бы реализовать проверку, когда пользователь заполняет эту информацию.- это хорошая идея, что модель представления реализует IDataErrorInfo для проверки?

Я хотел бы использовать IDataErrorInfo, но я не знаю, хорошая идея, что моя модель представления реализует этот интерфейс или лучше, если я создаю новый класс. Как наилучший способ получить валидацию с помощью IDataErrorInfo и шаблона MVVM?

EDIT: Я вижу, что в некоторых примерах реализация находится в модели (это не то же самое, что модель представления), но в моем случае модель в основном представляет собой объекты POCO, которые я создаю из своей базы данных при создании моя модель edmx с инфраструктурой сущностей, поэтому я бы хотел избежать необходимости изменять эти объекты, потому что, если мне не нужно обновлять мою модель, мне придется снова выполнить эту работу.

Спасибо.

+4

Хороший вопрос. +1 –

+3

Я бы сказал, что это очень хорошая идея для виртуальной машины для реализации 'IDataErrorInfo'. Этот интерфейс в значительной степени «помогает» с передачей информации пользователю (Просмотр) для фоновых ошибок (Ошибки в данных). это именно то, для чего нужна ВМ, и было бы совершенно правильно иметь ее там. [Комментарии в этом ответе] (http://stackoverflow.com/a/341832/1834662), а ниже под ним утверждается, что он есть в Модели. Определив его в другом классе, чем модель, и виртуальная машина не будет «неправильной» либо для абстракции, а просто не стоит этого. – Viv

+1

..cont'd. Если то, что вы проверяете с помощью «IDataErrorInfo», является такой сложной логикой, что вы захотите повторно использовать его, тогда я буквально переместил эти функциональные проверки в службу, а затем попросит VM реализовать интерфейс и VM использует службу для доступа к сложной логике проверки. Таким образом, вы получили свое повторное использование кода и совместное использование, а также оставайтесь чистым и простым с каждой виртуальной машиной, просто реализующей сами IDataErrorInfo. – Viv

ответ

2

Это всегда хорошая идея, чтобы отделить логику проверки от UI. Таким образом, использование IDataErrorInfo является правильным.

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

В нашем проекте проверка является более независимым компонентом, который может быть использован как уровнем представления, так и уровнем бизнес-логики по конфигурации. С точки зрения модели зрения он очень тонкий, содержащий только вызов и построение результата проверки внутри индексатора.

Кроме того, еще одно соображение - это INotifyDataErrorInfo, предоставляемый .Net 4.5 и Silverlight. Он предоставляет больше результатов валидации от одного свойства и асинхронной проверки для долговременной проверки, что мы хотим после того, как мы планировали обновить до .Net 4.5.

Надеюсь, это может вам помочь.

2

Если у вас есть объект или пользовательский тип (например, Person, Student и т. Д.), Который содержит данные, необходимо, чтобы вы реализовали IDataErrorInfo в своем Entity или Customtype. Предположим, у вас есть представление, позволяющее вводить данные Студента, и у вас есть ViewModel StudentViewModel, и у этого объекта ViewModel есть свойство Student типа Student, чье свойство (например, Name, Age и т. Д.) Привязаны к элементам управления View. Для Validations огня и изменения, чтобы отразить на пользовательском интерфейсе вы должны реализовать IDataErrorInfo в этом Студенческого класса не в вашей ViewModel, а также вы должны реализовать INotifyPropertyChanged в этом классе. Поэтому я понимаю, что если у вас есть несколько свойств в ViewModel, которые имеют тип (string и ValueTypes) и привязаны к View, и вы хотите применить к ним проверки, тогда вы должны реализовать IDataErrorInfo в ViewModel. И если у вас есть CustomType/Entity, тогда вы должны реализовать интерфейс в этих классах, а не в ViewModel.

Это не мое понимание это необходимо для реализации IDataErrorInfo и INotifyPropertyChanged в классе которого EndProperties (как имя, возраст Стьюдента) являются переплетены для управления Просмотр, если вы хотите Validations стрелять.

//Interface which has fields of Student class on which ValidationAttribute are to be applied 
public interface IStudent 
{ 
    [Required(ErrorMessage = "Name is required")] 
    string Name { get; set; } 

    [Range(10, 90, ErrorMessage = "Age should be between 10 and 90")] 
    int Age { get; set; } 
} 
//Partial Class to implement IStudent 
public partial class Student : IStudent 
{ 

} 

//POCO 
public partial class Student : INotifyPropertyChanged 
{ 
    private string name; 
    private int age; 

    public string Name 
    { 
     get 
     { 
      return name; 
     } 
     set 
     { 
      name = value; 

      Notify("Name"); 
     } 
    } 

    public int Age 
    { 
     get 
     { 
      return age; 
     } 
     set 
     { 
      age = value; 

      Notify("Age"); 
     } 
    } 
    private void Notify(string propName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propName)); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 
+0

Я понимаю эту идею. Тогда как я мог бы выполнить проверку в моих объектах POCO? это генерируется шаблоном T4 из моей модели edmx, созданной из моей базы данных. Если я обновляю свою базу данных и мне нужно снова создать сущности, я потерял все изменения (валидация в этом случае). Есть ли способ реализовать проверку в сущности, которые генерируются из базы данных? –

+0

Используете ли вы проверки на основе атрибутов? – ethicallogics

+0

К моменту времени я не использую какие-либо проверки, я пытаюсь решить лучший вариант. –

2

Я бы согласился с подавляющим большинством комментариев по этому вопросу, но я отвечаю, предлагая мое «обновление» этого интерфейса.

Проблема, которую я вижу с интерфейсом IDataErrorInfo, заключается в том, что она обрабатывает только одну ошибку за раз. Поэтому я добавил дополнительное поле в моем BaseDataType класса (базовый класс для всех моих типов данных):

protected ObservableCollection<string> errors = new ObservableCollection<string>(); 

Затем я добавил следующие свойства:

// this just enables me to add into the error collection from outside this class 
public ObservableCollection<string> ExternalErrors 
{ 
    get { return externalErrors; } 
} 

public override ObservableCollection<string> Errors 
{ 
    get 
    { 
     errors = new ObservableCollection<string>(); 
     // add properties to validate 
     errors.AddUniqueIfNotEmpty(this["Property1ToValidate"]); 
     errors.AddUniqueIfNotEmpty(this["Property2ToValidate"]); 
     errors.AddUniqueIfNotEmpty(this["Property3ToValidate"]); 
     // add external errors (from view models) 
     errors.AddRange(ExternalErrors); 
     return errors; 
    } 
} 

public virtual bool HasError 
{ 
    get { return Errors != null && Errors.Count > 0; } 
} 

Метод AddUniqueIfNotEmpty является метод расширения и я уверен, что вы все можете догадаться, что он делает.

Используя это, я могу напрямую связать коллекцию ошибок в представлениях и даже лучше привязать к свойству HasError с помощью BoolToVisibilityConverter, чтобы скрыть элемент управления, отображающий ошибки, когда коллекция пуста.

1
<TextBox Text="{Binding Path=MyCoolProperty, ValidationOnDataErrors=true}" 

может быть, я что-то пропустил, но если у вас есть привязки, как это - ваш класс с «MyCoolProperty» должно реализовать INotifyPropertyChanges И IDataErrorInfo - в противном случае он не будет работать.

, так что я бы сказал, что вопрос не является: «должен реализовать IDataErrorInfo», но, возможно, как реализовать IDataErrorInfo

Смежные вопросы