
You can use the IEditableObject implementation in the model class.
public class Person : INotifyPropertyChanged, IEditableObject { //ΡΡΡΠ»ΠΊΠ° Π½Π° ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Ρ
ΡΠ°Π½Π΅Π½ΠΈΡ ΠΏΡΠ΅Π΄ΡΠ΄.Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ Π½Π° Π²ΡΠ΅ΠΌΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ private Person _tempValues; public event PropertyChangedEventHandler PropertyChanged; public int Id { get; set; } private int _OrderNumber; public int OrderNumber { get => _OrderNumber; set { _OrderNumber = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OrderNumber))); } } private string _FirstName; public string FirstName { get => _FirstName; set { _FirstName = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FirstName))); } } private string _LastName; public string LastName { get => _LastName; set { _LastName = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LastName))); } } #region Π Π΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ IEditableObject /// <summary> /// ΠΠΎΠ³Π΄Π° Π½Π°ΡΠΈΠ½Π°Π΅ΡΡΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ /// </summary> public void BeginEdit() { _tempValues = new Person { Id = this.Id, OrderNumber = this.OrderNumber, FirstName = this.FirstName, LastName = this.LastName }; } /// <summary> /// ΠΠΎΠ³Π΄Π° ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΎ /// </summary> public void EndEdit() { _tempValues = null; } /// <summary> /// ΠΠΎΠ³Π΄Π° ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΡΠΌΠ΅Π½ΡΠ΅ΡΡΡ /// </summary> public void CancelEdit() { if (_tempValues == null) return; this.Id = _tempValues.Id; this.OrderNumber = _tempValues.OrderNumber; this.FirstName = _tempValues.FirstName; this.LastName = _tempValues.LastName; } #endregion }
For example, the DataGrid that is called "out of the box" supports calling corresponding methods, and in particular, calls CancelEdit() if you press Esc during editing a cell. Well, in the case of editing in textboxes, you can do this
public class MainViewModel : IMainViewModel, INotifyPropertyChanged { private readonly IPersonRepository _repo; private Person _selectedPerson; public event PropertyChangedEventHandler PropertyChanged; //ctor public MainViewModel(IPersonRepository repository) { _repo = repository ?? throw new ArgumentNullException(nameof(repository)); } public async Task LoadData() { People = new ObservableCollection<Person>(); var result = await _repo.GetPeopleOrderedByLastName(); List<Person> people = result.ToList(); for (int i = 0; i < people.Count; i++) { people[i].OrderNumber = i + 1; People.Add(people[i]); } } /// <summary> /// ΠΠΎΠ»Π»Π΅ΠΊΡΠΈΡ Π΄Π»Ρ ListView /// </summary> public ObservableCollection<Person> People { get; private set; } /// <summary> /// ΠΡΠ΄Π΅Π»Π΅Π½Π½ΡΠΉ Π² ListView ΡΠ΅Π»ΠΎΠ²Π΅ΠΊ /// </summary> public Person SelectedPerson { get => _selectedPerson; set { //ΠΎΡΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡ. _selectedPerson?.CancelEdit(); _selectedPerson = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedPerson))); //Π½Π°ΡΠΈΠ½Π°Π΅ΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ _selectedPerson?.BeginEdit(); } } /// <summary> /// ΠΠ½ΠΎΠΏΠΊΠ° ΠΠΎΡΠΎΠ²ΠΎ /// </summary> private ICommand _AddCommand; public ICommand AddCommand { get => _AddCommand = _AddCommand ?? new RelayCommand(OnAdd); } private async void OnAdd() { if (SelectedPerson == null) return; //Π·Π°ΠΊΠ°Π½ΡΠΈΠ²Π°Π΅ΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ SelectedPerson.EndEdit(); //ΠΎΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ Π² ΠΠ await _repo.UpdatePerson(SelectedPerson); SelectedPerson = null; //ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°Π΅ΠΌ ΡΠΏΠΈΡΠΎΠΊ ΠΈΠ· ΠΠ await LoadData(); } /// <summary> /// ΠΠ½ΠΎΠΏΠΊΠ° ΠΡΠΌΠ΅Π½Π° /// </summary> private ICommand _CancelCommand; public ICommand CancelCommand { get => _CancelCommand = _CancelCommand ?? new RelayCommand(OnCancel); } private void OnCancel() { if (SelectedPerson == null) return; //ΠΎΡΠΌΠ΅Π½ΡΠ΅ΠΌ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ SelectedPerson.CancelEdit(); } }
The whole example can be found here .
ModelinMVVM? - tym32167