EmployeeBrowseVM.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using InvestTracker.Entities;
  2. using Microsoft.EntityFrameworkCore;
  3. using Microsoft.IdentityModel.Tokens;
  4. using Prism.Commands;
  5. using Prism.Mvvm;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12. using System.Windows;
  13. namespace InvestTracker.VM
  14. {
  15. public class EmployeeBrowseVM : BindableBase
  16. {
  17. #region Команды
  18. public DelegateCommand UndoCommand { get; set; }
  19. public DelegateCommand SaveCommand { get; set; }
  20. public DelegateCommand NewCommand { get; set; }
  21. public DelegateCommand EditCommand { get; set; }
  22. public DelegateCommand DeleteCommand { get; set; }
  23. public DelegateCommand FindCommand { get; set; }
  24. public DelegateCommand ToggleFilterCommand { get; set; }
  25. #endregion
  26. /// <summary>
  27. /// Определяет можно ли редактировать значения в сетке данных
  28. /// </summary>
  29. public bool GridBlocked { get; set; }
  30. /// <summary>
  31. /// Контекст БД
  32. /// </summary>
  33. private InvestContext _dbContext;
  34. /// <summary>
  35. /// Определяет состояние приложения
  36. /// </summary>
  37. private bool isDirty = false;
  38. /// <summary>
  39. /// Список всех сотрудников
  40. /// </summary>
  41. public ObservableCollection<Employee> Employees { get; set; }
  42. /// <summary>
  43. /// Список всех должностей для выбора в колонках
  44. /// </summary>
  45. public ObservableCollection<Title> AllTitles { get; set; }
  46. /// <summary>
  47. /// Выбранный на данный момент сотрудник
  48. /// </summary>
  49. public Employee? SelectedEmployee { get; set; }
  50. /// <summary>
  51. /// По какой фамилии фильтровать поиск
  52. /// </summary>
  53. public string? FilterSurname { get; set; }
  54. /// <summary>
  55. /// По какой должности фильтровать поиск
  56. /// </summary>
  57. public Entities.Title? FilterTitle { get; set; }
  58. /// <summary>
  59. /// Активен ли фильтр в данный момент
  60. /// </summary>
  61. public bool FilterActive { get; set; }
  62. public EmployeeBrowseVM()
  63. {
  64. UndoCommand = new DelegateCommand(Undo_Executed, WhenDirty);
  65. SaveCommand = new DelegateCommand(Save_Executed, WhenDirty);
  66. NewCommand = new DelegateCommand(New_Executed, WhenClean);
  67. EditCommand = new DelegateCommand(Edit_Executed, WhenClean);
  68. DeleteCommand = new DelegateCommand(Delete_Executed, WhenClean);
  69. FindCommand = new DelegateCommand(Find_Executed, WhenClean);
  70. ToggleFilterCommand = new DelegateCommand(ToggleFilterCommand_Executed, WhenClean);
  71. GridBlocked = true;
  72. _dbContext = new InvestContext();
  73. Employees = new ObservableCollection<Employee>(_dbContext.Employees.ToList());
  74. AllTitles = new ObservableCollection<Title>(_dbContext.Titles.ToList());
  75. FilterActive = false;
  76. }
  77. /// <summary>
  78. /// Выполняет отмену
  79. /// </summary>
  80. private void Undo_Executed()
  81. {
  82. // http://stackoverflow.com/questions/5466677/ddg#17967959
  83. var changedEntries = _dbContext.ChangeTracker.Entries()
  84. .Where(x => x.State != EntityState.Unchanged)
  85. .ToList();
  86. foreach (var entry in changedEntries)
  87. {
  88. switch (entry.State)
  89. {
  90. case EntityState.Modified:
  91. entry.CurrentValues.SetValues(entry.OriginalValues);
  92. entry.State = EntityState.Unchanged;
  93. break;
  94. case EntityState.Added:
  95. entry.State = EntityState.Detached;
  96. break;
  97. case EntityState.Deleted:
  98. entry.State = EntityState.Unchanged;
  99. break;
  100. }
  101. }
  102. Employees = new ObservableCollection<Employee>(_dbContext.Employees.ToList());
  103. _dbContext.SaveChanges();
  104. GridBlocked = true;
  105. isDirty = false;
  106. RaisePropertyChanged(nameof(GridBlocked));
  107. RaisePropertyChanged(nameof(Employees));
  108. ReEvaluateCommands();
  109. }
  110. /// <summary>
  111. /// Сохраняет все изменения
  112. /// </summary>
  113. private void Save_Executed()
  114. {
  115. try
  116. {
  117. _dbContext.SaveChanges();
  118. } catch (DbUpdateException ex)
  119. {
  120. string message = "Введённые данные о сотруднике не верны.";
  121. if (ex.InnerException != null)
  122. {
  123. message += "\r\n" + ex.InnerException.Message;
  124. }
  125. MessageBox.Show(message);
  126. return;
  127. }
  128. GridBlocked = true;
  129. isDirty = false;
  130. RaisePropertyChanged(nameof(GridBlocked));
  131. ReEvaluateCommands();
  132. }
  133. /// <summary>
  134. /// Добавляет нового пользователя
  135. /// </summary>
  136. private void New_Executed()
  137. {
  138. Employee newEmployee = new Employee();
  139. _dbContext.Attach(newEmployee);
  140. Employees.Add(newEmployee);
  141. GridBlocked = false;
  142. isDirty = true;
  143. RaisePropertyChanged(nameof(GridBlocked));
  144. ReEvaluateCommands();
  145. }
  146. /// <summary>
  147. /// Переводит DataGrid в режим редактирования
  148. /// </summary>
  149. private void Edit_Executed()
  150. {
  151. GridBlocked = false;
  152. isDirty = true;
  153. RaisePropertyChanged(nameof(GridBlocked));
  154. ReEvaluateCommands();
  155. }
  156. /// <summary>
  157. /// Удаляет сотрудника
  158. /// </summary>
  159. private void Delete_Executed()
  160. {
  161. if (SelectedEmployee == null)
  162. {
  163. MessageBox.Show("Не выбрана строка для удаления");
  164. return;
  165. }
  166. MessageBoxResult result = MessageBox.Show(
  167. $"Удалить сотрудника: {SelectedEmployee.Surname} {SelectedEmployee.Name} {SelectedEmployee.Patronymic}",
  168. "Предупреждение",
  169. MessageBoxButton.OKCancel);
  170. if (result != MessageBoxResult.OK)
  171. {
  172. return;
  173. }
  174. _dbContext.Employees.Remove(SelectedEmployee);
  175. Employees.Remove(SelectedEmployee);
  176. isDirty = true;
  177. RaisePropertyChanged(nameof(isDirty));
  178. RaisePropertyChanged(nameof(SelectedEmployee));
  179. ReEvaluateCommands();
  180. }
  181. /// <summary>
  182. /// Выполняет поиск
  183. /// </summary>
  184. private void Find_Executed()
  185. {
  186. // 1. Установить список сотрудников по условиям
  187. Func<Employee, bool> filter = (Employee e) => {
  188. if (FilterSurname.IsNullOrEmpty() == false)
  189. {
  190. if (e.Surname != FilterSurname)
  191. {
  192. // Не совпадают фамилии
  193. return false;
  194. }
  195. }
  196. if (FilterTitle != null)
  197. {
  198. if (e.Title != FilterTitle)
  199. {
  200. // Не совпадают должности
  201. return false;
  202. }
  203. }
  204. return true;
  205. };
  206. var filteredEmployees = _dbContext.Employees
  207. .Where(filter)
  208. .ToList();
  209. // 2. Проверить результаты
  210. if (filteredEmployees.Count == 0)
  211. {
  212. MessageBox.Show("Не найдено ни одного сотрудника, используя заданные параметры");
  213. return;
  214. }
  215. // 3. Перезаписать сотрудников
  216. Employees = new ObservableCollection<Employee>(filteredEmployees);
  217. RaisePropertyChanged(nameof(Employees));
  218. }
  219. /// <summary>
  220. /// CanExecute когда isDirty = false
  221. /// </summary>
  222. private bool WhenClean()
  223. {
  224. if (isDirty == false)
  225. {
  226. return true;
  227. } else
  228. {
  229. return false;
  230. }
  231. }
  232. /// <summary>
  233. /// CanExecute когда isDirty = true
  234. /// </summary>
  235. private bool WhenDirty()
  236. {
  237. if (isDirty == true)
  238. {
  239. return true;
  240. }
  241. else
  242. {
  243. return false;
  244. }
  245. }
  246. private void ToggleFilterCommand_Executed()
  247. {
  248. FilterActive = !FilterActive;
  249. if (FilterActive == false)
  250. {
  251. // Сбрасываем фильтр
  252. Employees = new ObservableCollection<Employee>(_dbContext.Employees.ToList());
  253. RaisePropertyChanged(nameof(Employees));
  254. }
  255. RaisePropertyChanged(nameof(FilterActive));
  256. }
  257. /// <summary>
  258. /// Заставляет все команды вызвать свои методы .RaiseExecuteChanged
  259. /// </summary>
  260. private void ReEvaluateCommands()
  261. {
  262. UndoCommand.RaiseCanExecuteChanged();
  263. SaveCommand.RaiseCanExecuteChanged();
  264. NewCommand.RaiseCanExecuteChanged();
  265. EditCommand.RaiseCanExecuteChanged();
  266. DeleteCommand.RaiseCanExecuteChanged();
  267. FindCommand.RaiseCanExecuteChanged();
  268. ToggleFilterCommand.RaiseCanExecuteChanged();
  269. }
  270. }
  271. }