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 => _roomId; set { if (value == _roomId) return; _roomId = value; OnPropertyChanged(); } } public string Number { get => _number; set { if (value == _number) return; _number = value; OnPropertyChanged(); } } public RoomTypes Type { get => _type; set { if (value == _type) return; _type = value; OnPropertyChanged(); } } public virtual IList<Client> Clients { get => _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<Client>(); } }
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. InterfaceIDataStore<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<Cat> GetItem(int id) { //code } public async Task<IEnumerable<Cat>> GetItems() { //code } public async Task<bool> RemoveItem(int id) { //code } public async Task<bool> UpdateItem(Cat item) { //code }
}
Definitely.
BaseViewModel
Don't write in all of us.Model
ImplementationINotifyPropertyChanged
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<T>(ref T store, T value, [CallerMemberName] string prop = "") { if (EqualityComparer<T>.Default.Equals(store, value)) return false; store = value; OnPropertyChanged(prop); return true; }
}
It is now possible to avoid implementation
INotifyPropertyChanged
and just cause the methodSetProperty
specific characteristicsViewModel
class CatViewModel : BaseViewModel
{
private CatDataStore<Cat> _store = new CatDataStore<Cat>();
private string _name;//Это свойство нужно будет забиндить ко View public string Name { get => _name; set => SetProperty(ref _name, value); } public ICommand AddCatCommand { get { return new Command((_) => { Cat cat = new Cat { Name = this.Name }; //можно и без this, это для наглядности. _store.AddItem(cat); }); } }
}
Class
Command
:class Command : ICommand
{
public event EventHandler CanExecuteChanged;private Action<object> _execute; private Func<object, bool> _canExecute; public Command(Action<object> execute, Func<object, bool> canExecute = null) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null || CanExecute(parameter); } public void Execute(object parameter) { _execute.Invoke(parameter); }
}