How can data be added? C# WPF MVM



  • Status:

    I'm studying MVM. If I'm not mistaken, we need the Model to run a business logic (service) in it, and ViewModel is needed to make the link between View and Model.

    The problem is:

    Where do we put the data in the database? ViewModel or Model?

    To date, this has been implemented in ViewModel:

    public ICommand AddRoomCommand =>
                _addRoomCommand ??
                (_addRoomCommand = new RelayCommand(
                    () =>
                    {
                        Context.Rooms.Add(new Room
                        {
                            Number = RoomInfo.Number,
                            Type = RoomInfo.Type
                        });
                        Context.SaveChanges();
                    },
                    () =>
                    {
                        if (string.IsNullOrEmpty(RoomInfo.Number) || RoomInfo.Type == RoomTypes.None)
                        {
                            return false;
                        }
                        return true;
                    }));
    

    By the way, here's the Model Room:

    public class Room : INotifyPropertyChanged
        {
            private RoomTypes _type;
            private string _number;
            private int _roomId;
            private IList<Client> _clients;
    
        public int RoomId
        {
            get =&gt; _roomId;
            set
            {
                if (value == _roomId) return;
                _roomId = value;
                OnPropertyChanged();
            }
        }
    
        public string Number
        {
            get =&gt; _number;
            set
            {
                if (value == _number) return;
                _number = value;
                OnPropertyChanged();
            }
        }
    
        public RoomTypes Type
        {
            get =&gt; _type;
            set
            {
                if (value == _type) return;
                _type = value;
                OnPropertyChanged();
            }
        }
    
        public virtual IList&lt;Client&gt; Clients
        {
            get =&gt; _clients;
            set
            {
                if (Equals(value, _clients)) return;
                _clients = value;
                OnPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    
        public Room()
        {
            _clients = new List&lt;Client&gt;();
        }
    }
    

    If you still have to do this in the Model, please tell me how to do it best.

    This project isn't mine, I took it from here: https://github.com/mentapro/HotelSystem



  • Model Could be not only a business logic, but just data. Separate how comfortable you are.

    This is an example of working with the OBD. For starters, I've identified Model(Cat) - to be rude to the data warehouse. Interface IDataStore<T> for each class to work with a specificModel

    Ours. Model:

    class Cat
    {
        public int Id { get; set; }
        public string Name{ get; set; }
    }
    

    The logic to work with ours. Model

    interface IDataStore<T>
    {
        Task<bool> AddItem(T item);
        Task<bool> RemoveItem(int id);
        Task<T> GetItem(int id);
        Task<IEnumerable<T>> GetItems();
        Task<bool> UpdateItem(T item);
    }
    

    class CatDataStore<Cat> : IDataStore<Cat>
    {
    public async Task<bool> AddItem(Cat item)
    {
    //code
    }

    public async  Task&lt;Cat&gt; GetItem(int id)
    {
        //code
    }
    
    public async Task&lt;IEnumerable&lt;Cat&gt;&gt; GetItems()
    {
        //code
    }
    
    public async Task&lt;bool&gt; RemoveItem(int id)
    {
        //code
    }
    
    public async Task&lt;bool&gt; UpdateItem(Cat item)
    {
        //code
    }
    

    }

    Definitely. BaseViewModel Don't write in all of us. Model Implementation INotifyPropertyChanged

    class BaseViewModel : INotifyPropertyChanged
    {
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string prop = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
    }
    
    //Метод будет вызывать OnPropertyChanged для конкретного свойства ViewModel, которое будет забинжено к какому-то UI-элементу во ```View```. 
    
    
    protected bool SetProperty&lt;T&gt;(ref T store, T value, 
                                 [CallerMemberName] string prop = "")
    {
        if (EqualityComparer&lt;T&gt;.Default.Equals(store, value))
            return false;
    
        store = value;
        OnPropertyChanged(prop);
        return true;
    }
    

    }

    It is now possible to avoid implementation INotifyPropertyChanged and just cause the method SetProperty specific characteristics ViewModel

    class CatViewModel : BaseViewModel
    {
    private CatDataStore<Cat> _store = new CatDataStore<Cat>();
    private string _name;

    //Это свойство нужно будет забиндить ко View
    public string Name { get =&gt; _name; set =&gt; SetProperty(ref _name, value); }
    
    
    public ICommand AddCatCommand
    {
         get 
         {
            return new Command((_) =&gt; 
            {
                 Cat cat = new Cat { Name = this.Name }; //можно и без this, это для наглядности.
                 _store.AddItem(cat);
            });
         }
    }
    

    }

    Class Command:

    class Command : ICommand
    {
    public event EventHandler CanExecuteChanged;

    private Action&lt;object&gt; _execute;
    private Func&lt;object, bool&gt; _canExecute;
    
    public Command(Action&lt;object&gt; execute, Func&lt;object, bool&gt; canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || CanExecute(parameter);
    }
    
    public void Execute(object parameter)
    {
        _execute.Invoke(parameter);
    }
    

    }



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2