/
makarenkova
/
c_sharp
Обзор
Документация
Войти
/
makarenkova
/
c_sharp
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
PlannerProject/Modules/Planner.Modules.Main/ViewModels/MainViewModel.cs
398 строк
15 KB
Makarenkova Vera
Исправлены комментарии
16 май 2026, 16:38
16 май 2026, 16:38
66b2bf6
Код
Авторство
О чём код?
using Planner.Modules.Main.Events; using Planner.Modules.Main.Models; using Planner.Modules.Main.Services; using Planner.Shared; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; namespace Planner.Modules.Main.ViewModels { public class MainViewModel : BindableBase { private readonly IEventAggregator _eventAggregator; private readonly IDBService _dbService; private readonly IDialogService _dialogService; private DateTime _currentDate; // Поле для хранения оригинальной заметки при редактировании private Note _originalNote; // Поле для отслеживания изменений текста private string _tempNoteText; // Свойство для временного текста заметки public string TempNoteText { get => _tempNoteText; set { if (SetProperty(ref _tempNoteText, value)) { // При изменении текста обновляем команды SaveNoteCommand.RaiseCanExecuteChanged(); DeleteNoteCommand.RaiseCanExecuteChanged(); } } } private Note _currNote; public Note CurrNote { get => _currNote; set => SetProperty(ref _currNote, value); } private WeekViewModel _currentWeek; public WeekViewModel CurrentWeek { get => _currentWeek; set => SetProperty(ref _currentWeek, value); } public DelegateCommand PreviousWeekCommand { get; } public DelegateCommand NextWeekCommand { get; } public DelegateCommand CurrentWeekCommand { get; } public DelegateCommand SaveNoteCommand { get; } public DelegateCommand DeleteNoteCommand { get; } public DelegateCommand<DateTime?> AddTaskCommand { get; } public DelegateCommand<TaskViewModel> ToggleTaskCompletedCommand { get; } public DelegateCommand<TaskViewModel> ExitEditModeCommand { get; } public DelegateCommand<TaskViewModel> BeginEditTaskCommand { get; } // Команды для перетаскивания задач public DelegateCommand<TaskViewModel> DragTaskStartCommand { get; } public DelegateCommand<object> DropTaskCommand { get; } public MainViewModel(IEventAggregator eventAggregator, IDBService taskService, IDialogService dialogService) { _eventAggregator = eventAggregator; _dbService = taskService; _dialogService = dialogService; _currentDate = DateTime.Today; // Подписываемся на событие удаления задачи _eventAggregator.GetEvent<TaskDeletedEvent>().Subscribe(OnTaskDeleted); // Подписываемся на событие обновления задачи _eventAggregator.GetEvent<TaskUpdatedEvent>().Subscribe(OnTaskUpdated); // Подписываемся на событие изменения задачи _eventAggregator.GetEvent<TaskChangedEvent>().Subscribe(OnTaskChanged); BeginEditTaskCommand = new DelegateCommand<TaskViewModel>(BeginEditTask); ExitEditModeCommand = new DelegateCommand<TaskViewModel>(ExitEditMode); // Команды перетаскивания DragTaskStartCommand = new DelegateCommand<TaskViewModel>(DragTaskStart); DropTaskCommand = new DelegateCommand<object>(DropTask); PreviousWeekCommand = new DelegateCommand(PreviousWeek); NextWeekCommand = new DelegateCommand(NextWeek); CurrentWeekCommand = new DelegateCommand(CurrWeek); AddTaskCommand = new DelegateCommand<DateTime?>(AddTask); ToggleTaskCompletedCommand = new DelegateCommand<TaskViewModel>(ToggleTaskCompleted); // Команды для заметок SaveNoteCommand = new DelegateCommand(SaveNote, CanSaveNote); DeleteNoteCommand = new DelegateCommand(DeleteNote, CanDeleteNote); LoadCurrentWeek(); LoadCurrentNote(); } private void OnTaskDeleted(TaskItem deletedTask) { LoadCurrentWeek(); } private void OnTaskUpdated(TaskItem updatedTask) { LoadCurrentWeek(); } private void OnTaskChanged(TaskItem changedTask) { LoadCurrentWeek(); } private void BeginEditTask(TaskViewModel task) { task?.BeginEdit(); } private void ExitEditMode(TaskViewModel task) { task?.ExitEditMode(); } private void ToggleTaskCompleted(TaskViewModel task) { // Сохраняем изменеённое IsCompleted (галочка о выполнении) в БД _dbService.UpdateTask(task.GetModel()); } private void LoadCurrentWeek() { // номер недели для текущего дня var weekNumber = DBService.GetWeekNumber(_currentDate); // получаем задачи для текущей недели var tasks = _dbService.GetTasksForWeek(_currentDate.Year, weekNumber); CurrentWeek = new WeekViewModel { Year = _currentDate.Year, WeekNumber = weekNumber, Days = CreateDaysForWeek(_currentDate.Year, weekNumber, tasks) }; // Публикуем событие о смене недели (для Shell) _eventAggregator.GetEvent<WeekChangedEvent>() .Publish(CurrentWeek.WeekDisplay); } private ObservableCollection<DayViewModel> CreateDaysForWeek(int year, int weekNumber, List<TaskItem> tasks) { var days = new ObservableCollection<DayViewModel>(); // дата понедельника текущей недели var startOfWeek = DBService.GetWeekDateRange(year, weekNumber).startDate; var today = DateTime.Today; for (int i = 0; i < 7; i++) { var currentDay = startOfWeek.AddDays(i); var dayTasks = tasks.Where(t => t.Date.Date == currentDay.Date).OrderBy(t => t.Date).ToList(); // Создаем TaskViewModel для каждой задачи var taskVM = new ObservableCollection<TaskViewModel>(); foreach (var task in dayTasks) { taskVM.Add(new TaskViewModel(task, _dbService, _eventAggregator, _dialogService)); } var dayVM = new DayViewModel { Date = currentDay, Tasks = taskVM, IsCurrentDay = currentDay.Date == today.Date }; days.Add(dayVM); } return days; } private void PreviousWeek() { _currentDate = _currentDate.AddDays(-7); LoadCurrentWeek(); LoadCurrentNote(); } private void NextWeek() { _currentDate = _currentDate.AddDays(7); LoadCurrentWeek(); LoadCurrentNote(); } private void CurrWeek() { _currentDate = DateTime.Today; LoadCurrentWeek(); LoadCurrentNote(); } private void AddTask(DateTime? date) { if (date.HasValue) { // Устанавливаем время на начало следующего часа от текущего времени DateTime now = DateTime.Now; DateTime nextHourStart = new DateTime( now.Year, now.Month, now.Day, now.Hour, 0, 0).AddHours(1); // Если время следующего часа равно 00:00, устанавливаем 23:00 TimeSpan timeToUse = nextHourStart.TimeOfDay; if (timeToUse == TimeSpan.Zero) { timeToUse = new TimeSpan(23, 0, 0); } // Сохраняем выбранную дату, но с временем начала следующего часа (или 23:00) DateTime taskDateTime = date.Value.Date + timeToUse; var task = new TaskItem { Date = taskDateTime, Title = "Новая задача", Description = "", IsCompleted = false, Priority = Priority.Low }; _dbService.AddTask(task); LoadCurrentWeek(); // Перезагружаем, создадутся новые TaskViewModel } } // ---------- заметки --------------- private void LoadCurrentNote() { // Загружаем заметку из БД _originalNote = _dbService.GetNoteForWeek(_currentDate); if (_originalNote != null) { // Если заметка существует, создаём копию для редактирования CurrNote = new Note { Id = _originalNote.Id, Year = _originalNote.Year, WeekNumber = _originalNote.WeekNumber, Description = _originalNote.Description }; } else { // Если заметки нет, создаём новую int weekNumber = DBService.GetWeekNumber(_currentDate); CurrNote = new Note { Year = _currentDate.Year, WeekNumber = weekNumber, Description = string.Empty }; } // Синхронизируем временный текст с загруженной заметкой TempNoteText = CurrNote.Description; } private bool CanSaveNote() { // Текст заметки не пустая строка И // (заметки для этой недели ещё нет в БД ИЛИ текст заметки изменился) return !string.IsNullOrWhiteSpace(TempNoteText) && (_originalNote == null || TempNoteText != _originalNote.Description); } private void SaveNote() { CurrNote.Description = TempNoteText; // Есть ли в БД заметка для текущей недели if (_originalNote != null) // обновляем _dbService.UpdateNote(CurrNote); else // Если нет, создаём новую заметку в БД _dbService.AddNote(CurrNote); // Перезагружаем заметку LoadCurrentNote(); SaveNoteCommand.RaiseCanExecuteChanged(); DeleteNoteCommand.RaiseCanExecuteChanged(); } private bool CanDeleteNote() { // Можно удалить, если заметка существует в БД return _originalNote != null; } private void DeleteNote() { // Удаляем заметку из БД _dbService.DeleteNote(_originalNote.Id); // Сбрасываем состояния _originalNote = null; TempNoteText = string.Empty; // Перезагружаем заметку (создаст новую пустую CurrNote) LoadCurrentNote(); // Обновляем состояние команд SaveNoteCommand.RaiseCanExecuteChanged(); DeleteNoteCommand.RaiseCanExecuteChanged(); } // ---------- перетаскивание задач --------------- // Поле для хранения перетаскиваемой задачи private TaskViewModel _draggedTask; // Начало перетаскивания задачи (сохраняем задачу для последующего использования) private void DragTaskStart(TaskViewModel task) { // Запрещаем перетаскивание выполненных задач if (task.IsCompleted) return; _draggedTask = task; } // Обработка события Drop (отпускание задачи) private void DropTask(object parameter) { if (_draggedTask == null) return; // Дополнительная проверка: если задача выполнена, запрещаем изменение даты if (_draggedTask.IsCompleted) { _draggedTask = null; return; } // Параметр должен быть DateTime (дата целевого дня) if (parameter is DateTime targetDate) { // Находим исходный DayViewModel (откуда перетащили) var sourceDay = FindDayViewModelByTask(_draggedTask); if (sourceDay == null) return; // Если задача уже находится в целевом дне, ничего не делаем if (sourceDay.Date.Date == targetDate.Date) { _draggedTask = null; return; } // Обновляем дату задачи, сохраняя исходное время var taskItem = _draggedTask.GetModel(); taskItem.Date = targetDate.Date + taskItem.Date.TimeOfDay; // Сохраняем изменения в базе данных _dbService.UpdateTask(taskItem); // Публикуем событие об изменении задачи для обновления UI _eventAggregator.GetEvent<TaskChangedEvent>().Publish(taskItem); } _draggedTask = null; } // Находит DayViewModel, содержащий указанную задачу private DayViewModel FindDayViewModelByTask(TaskViewModel task) { if (CurrentWeek?.Days == null) return null; foreach (var day in CurrentWeek.Days) { if (day.Tasks.Contains(task)) return day; } return null; } } }