CRUD done on WPF MVVM. Control RadGridView but it is not important in principle. With the teams figured out. Stuck with validation ..

This is my viewModel

public class DirectoryViewModel : TurnikamBaseModel { private TurnikamEntities _dataContext; private ObservableCollection<TBL_SEX> tbl_sex; public ObservableCollection<TBL_SEX> 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<TBL_SEX>(_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; } } 
  • And what is necessary to validate? - Vlad
  • You need to validate what we enter into the grid cells. Check for emptiness, for maximum length and so on. Without MVVM there is nothing complicated about it. And I don’t even know where to start. Entity Framework also hinders a little, but there is no way back) I didn’t find anything terrible in the internet .. - alirasul
  • Hm And where does the EF? When using MVVM, your UI sees not Entity, but VM objects. - VladD
  • So how do I add validation. EF classes do partial? Just do not understand how to do it correctly. - alirasul
  • Are you interested in EF or WPF validation? - Vlad

1 answer 1

Actually, there are 3 (as far as I know) options for validation in WPF:

1. Validation on exceptions.

The easiest way. It looks like this:

XAML

 <TextBox Text="{Binding String1, ValidateOnExceptions=True}"/> 

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. Validation of the rules.

An example on msdn . In short, a specific rule is created (a successor to the ValidationRule), which is used by the Binding tag in the XAML markup.

3. Validation at the data source (or something like that).

An example on msdn . You can use attributes from DataAnnotations or describe custom validation rules. The ViewModel should implement the IDataErrorInfo interface. An example using the Required attribute:

XAML:

 <TextBox Text="{Binding String1, ValidatesOnDataErrors=True, UpdateSourceTrigger=PropertyChanged}"/> 

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<ValidationResult>(); var context = new ValidationContext(this, null, null) { MemberName = propertyName }; if (!Validator.TryValidateProperty(value, context, results)) { return results.First().ErrorMessage; } return string.Empty; } } 

UPD

I wouldn’t recommend mixing Model validation and ViewModel. Therefore, for those models that are exposed to the outside and that need to be somehow checked it makes sense to start the ViewModel. The implementation of IDataErrorInfo can be taken from the example above and thrust it into the base 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"); } } } 
  • It does not come to me how to use the 3rd option in my cases. Here I have a table in the database TBL_SEX {Guid sexGUID; string SexName}. I created a private ObservableCollection <TBL_SEX> tbl_sex; Where will I get validation? - alirasul
  • one
    Updated the answer. Validation will be in the ViewModel wrapper over TBL_SEX. Accordingly, not TBL_SEX objects, but TblSexVm objects will be exposed to the outside. - Vlad
  • ObservableCollection <TblSexVm> - Vlad
  • tbl_sex = new ObservableCollection<TblSexVm>(как заполнить?) - alirasul
  • one
    tbl_sex = new ObservableCollection<TblSexVm>(_dataContext.TBL_SEX.Select(_ => new TblSexVm(_)); and then make sure that addition and deletion take place in both collections: tbl_sex and _dataContext.TBL_SEX.