Страницы

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

суббота, 21 декабря 2019 г.

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

#c_sharp #wpf #entity_framework #mvvm


Делаю 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;
        }
    }

    


Ответы

Ответ 1



Собственно, есть 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"); } } }

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

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