master
  1using System;
  2using System.Collections.Generic;
  3using System.ComponentModel;
  4using System.Linq.Expressions;
  5using System.Windows;
  6using MVPtoMVVM.domain;
  7using MVPtoMVVM.repositories;
  8using System.Linq;
  9
 10namespace MVPtoMVVM.mvvm.viewmodels
 11{
 12    public class TodoItemViewModel : INotifyPropertyChanged, IDataErrorInfo
 13    {
 14        private readonly ITodoItemRepository todoItemRepository;
 15        private Synchronizer<TodoItemViewModel> synchronizer;
 16        public event PropertyChangedEventHandler PropertyChanged = (o, e) => { };
 17        public int Id { get; set; }
 18        public IObservableCommand SaveCommand { get; set; }
 19        public IObservableCommand DeleteCommand { get; set; }
 20        public MainWindowViewModel Parent { get; set; }
 21        private IDictionary<string, IValidation> validations;
 22        public bool IsDirty { get; set; }
 23
 24        public TodoItemViewModel(ITodoItemRepository todoItemRepository)
 25        {
 26            this.todoItemRepository = todoItemRepository;
 27            SaveCommand = new SimpleCommand(Save, CanSave);
 28            DeleteCommand = new SimpleCommand(Delete);
 29            synchronizer = new Synchronizer<TodoItemViewModel>(() => PropertyChanged);
 30            validations = new Dictionary<string, IValidation>
 31                              {
 32                                  {"Description", new Validation(() => !string.IsNullOrEmpty(Description), "Cannot have an empty description.")},
 33                                  {"DueDate", new Validation(() => DueDate >= DateTime.Today, "Due Date must occur on or after today.")}
 34                              };
 35        }
 36
 37        private void Delete()
 38        {
 39            todoItemRepository.Delete(Id);
 40            Parent.TodoItems.Remove(this);
 41        }
 42
 43        private bool CanSave()
 44        {
 45            return validations.Values.All(x => x.IsValid) && IsDirty;
 46        }
 47
 48        private void Save()
 49        {
 50            var todoItem = todoItemRepository.Get(Id) ?? new TodoItem();
 51            todoItem.DueDate = DueDate;
 52            todoItem.Description = Description;
 53            todoItemRepository.Save(todoItem);
 54            IsDirty = false;
 55        }
 56
 57        private string description;
 58        public string Description
 59        {
 60            get { return description; }
 61            set
 62            {
 63                description = value;
 64                IsDirty = true;
 65                Update(x => x.Description);
 66                SaveCommand.Changed();
 67            }
 68        }
 69
 70        private void Update(Expression<Func<TodoItemViewModel, object>> func)
 71        {
 72            synchronizer.Update(this, func);
 73        }
 74
 75        private DateTime dueDate;
 76        public DateTime DueDate
 77        {
 78            get { return dueDate; }
 79            set
 80            {
 81                dueDate = value;
 82                IsDirty = true;
 83                Update(x => x.DueDate);
 84                Update(x => x.ShowDueSoonAlert);
 85                SaveCommand.Changed();
 86            }
 87        }
 88
 89        public Visibility ShowDueSoonAlert
 90        {
 91            get
 92            {
 93                return DueDate <= DateTime.Today.AddDays(1) ? Visibility.Visible : Visibility.Hidden;
 94            }
 95        }
 96
 97        public string this[string columnName]
 98        {
 99            get
100            {
101                var validation = validations[columnName];
102                return validation.IsValid ? null : validation.Message;
103            }
104        }
105
106        public string Error
107        {
108            get { return string.Empty; }
109        }
110    }
111}