Страницы

Поиск по вопросам

понедельник, 12 ноября 2018 г.

WPF MVVM Entity Framework. Проблема с валидацией

Делаю CRUD на WPF MVVM. Контрол RadGridView но это в принципе не важно. С командами разобрался. Застрял с валидацией..
Это моя viewModel
public class DirectoryViewModel : TurnikamBaseModel { private TurnikamEntities _dataContext;
private ObservableCollection tbl_sex;
public ObservableCollection Tbl_sex { get { return tbl_sex; } set { tbl_sex = value; } }
private TBL_SEX selectedSex;
public TBL_SEX SelectedSex { get { return selectedSex; } set { if (this.selectedSex != value) { selectedSex = value; ((RelayCommand)this.SexDeleteCommand).IsEnabled = true; this.OnPropertyChanged(() => this.selectedSex); } } }
public DirectoryViewModel() { _dataContext = new TurnikamEntities(); tbl_sex = new ObservableCollection(_dataContext.TBL_SEX);
sexSave = new RelayCommand(SexSave) { IsEnabled = true }; sexAdd = RadGridViewCommands.BeginInsert; sexDelete = new RelayCommand(SexDelete) { IsEnabled = false }; }
ICommand sexSave; ICommand sexAdd; ICommand sexDelete;
public ICommand SexSaveCommand { get { return sexSave; } set { sexSave = value; } }
private void SexSave() { _dataContext.SaveChanges(); }
public ICommand SexAddCommand { get { return sexAdd; } }
public ICommand SexDeleteCommand { get { return sexDelete; } }
private void SexDelete() { if (SelectedSex != null) { if (SelectedSex.SexGUID!=Guid.Empty) { this._dataContext.TBL_SEX.DeleteObject(SelectedSex); } Tbl_sex.Remove(SelectedSex); OnPropertyChanged("Tbl_sex"); } else { ((RelayCommand)this.SexDeleteCommand).IsEnabled = false; } }


Ответ

Собственно, есть 3 (насколько мне известно) варианта валидации в WPF:
1. Валидация на исключениях.
Самый простой способ. Выглядит примерно так:
XAML

ViewModel
class SomeObject { ... public string String1 { get { return _string1; } set { if (_string1 != value) { if (string.IsNullOrEmpty(_string1)) throw new ArgumentException("value");
_string1 = value; OnPropertyChanged("String1"); } } } private string _string1; }
2. Валидация на правилах.
Пример на msdn. Если коротко, то создается определенное правило (наследник ValidationRule), которое используется тэге Binding в XAML разметке.
3. Валидация на источнике данных (или как-то так).
Пример на msdn. Можно использовать атрибуты из DataAnnotations или описывать кастомные правила валидации. ViewModel должна реализовать интерфейс IDataErrorInfo. Пример с использованием атрибута Required
XAML:

ViewModel
public class SomeObject : INotifyPropertyChanged, IDataErrorInfo { ...
[Required(AllowEmptyStrings=false, ErrorMessage="Hello, world!")] public string String1 { get { return _string1; } set { if (_string1 != value) { _string1 = value; OnPropertyChanged("String1"); } } }
private string _string1;
public string Error { get { throw new NotImplementedException(); } }
string IDataErrorInfo.this[string propertyName] { get { return Validate(propertyName); } }
private string Validate(string propertyName) { var value = GetType().GetProperty(propertyName).GetValue(this, null); var results = new List();
var context = new ValidationContext(this, null, null) { MemberName = propertyName };
if (!Validator.TryValidateProperty(value, context, results)) { return results.First().ErrorMessage; }
return string.Empty; } }
UPD
Я бы не советовал смешивать валидацию Model и ViewModel. Поэтому для тех моделей, которые выставляются наружу и которые нужно каким-то образом проверять имеет смысл завести ViewModel. Реализацию IDataErrorInfo можно взять из примера выше и засунуть ее в базовую ViewModel:
class TblSexVm : SomeObject //(читать BaseViewModel) { TBL_SEX Model{get; private set;}
public TblSexVm(TBL_SEX model) { Model = model; }
[Required(AllowEmptyStrings=false, ErrorMessage="Hello, world!")] public string SexName { get { return Model.SexName; } set { if (Model.SexName != value) { Model.SexName = value; OnPropertyChanged("SexName"); } } }

Комментариев нет:

Отправить комментарий