267 lines
8.5 KiB
C#
267 lines
8.5 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.ComponentModel;
|
||
using System.Linq;
|
||
using System.Windows.Data;
|
||
using System.Windows.Input;
|
||
|
||
namespace XLAB2
|
||
{
|
||
internal sealed class AccountingBookDirectoryWindowViewModel : ObservableObject
|
||
{
|
||
private readonly IDialogService _dialogService;
|
||
private readonly DocumentNumberDirectoryService _service;
|
||
private string _searchText;
|
||
private GroupOption _selectedItem;
|
||
private string _statusText;
|
||
|
||
public AccountingBookDirectoryWindowViewModel(DocumentNumberDirectoryService service, IDialogService dialogService)
|
||
{
|
||
_service = service ?? throw new ArgumentNullException("service");
|
||
_dialogService = dialogService ?? throw new ArgumentNullException("dialogService");
|
||
|
||
Items = new ObservableCollection<GroupOption>();
|
||
ItemsView = CollectionViewSource.GetDefaultView(Items);
|
||
ItemsView.Filter = FilterItems;
|
||
|
||
AddCommand = new RelayCommand(delegate { AddItem(); });
|
||
DeleteCommand = new RelayCommand(delegate { DeleteSelectedItem(); }, delegate { return SelectedItem != null; });
|
||
EditCommand = new RelayCommand(delegate { EditSelectedItem(); }, delegate { return SelectedItem != null; });
|
||
RefreshCommand = new RelayCommand(delegate { RefreshItems(null); });
|
||
|
||
UpdateStatus();
|
||
}
|
||
|
||
public ICommand AddCommand { get; private set; }
|
||
|
||
public ICommand DeleteCommand { get; private set; }
|
||
|
||
public ICommand EditCommand { get; private set; }
|
||
|
||
public ObservableCollection<GroupOption> Items { get; private set; }
|
||
|
||
public ICollectionView ItemsView { get; private set; }
|
||
|
||
public ICommand RefreshCommand { get; private set; }
|
||
|
||
public string SearchText
|
||
{
|
||
get { return _searchText; }
|
||
set
|
||
{
|
||
if (SetProperty(ref _searchText, value))
|
||
{
|
||
ItemsView.Refresh();
|
||
UpdateStatus();
|
||
}
|
||
}
|
||
}
|
||
|
||
public GroupOption SelectedItem
|
||
{
|
||
get { return _selectedItem; }
|
||
set
|
||
{
|
||
if (SetProperty(ref _selectedItem, value))
|
||
{
|
||
RaiseCommandStates();
|
||
}
|
||
}
|
||
}
|
||
|
||
public string StatusText
|
||
{
|
||
get { return _statusText; }
|
||
private set { SetProperty(ref _statusText, value); }
|
||
}
|
||
|
||
public void Initialize()
|
||
{
|
||
RunOperation(delegate { RefreshItems(null); }, false);
|
||
}
|
||
|
||
private void AddItem()
|
||
{
|
||
var result = _dialogService.ShowAccountingBookEditDialog(new GroupOption(), true, Items.ToList());
|
||
if (result == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
RunOperation(delegate
|
||
{
|
||
var items = CloneItems(Items);
|
||
items.Add(CloneItem(result));
|
||
_service.SaveAccountingBooks(items);
|
||
RefreshItems(result.Key);
|
||
_dialogService.ShowInfo("Запись справочника добавлена.");
|
||
}, true);
|
||
}
|
||
|
||
private bool Contains(string source, string searchText)
|
||
{
|
||
return !string.IsNullOrWhiteSpace(source)
|
||
&& source.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0;
|
||
}
|
||
|
||
private void DeleteSelectedItem()
|
||
{
|
||
if (SelectedItem == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var selectedItem = SelectedItem;
|
||
if (!_dialogService.Confirm(string.Format("Удалить книгу учета \"{0}\"?", selectedItem.Title)))
|
||
{
|
||
return;
|
||
}
|
||
|
||
RunOperation(delegate
|
||
{
|
||
var items = CloneItems(Items);
|
||
items.RemoveAll(delegate(GroupOption item)
|
||
{
|
||
return string.Equals(item.Key, selectedItem.Key, StringComparison.OrdinalIgnoreCase);
|
||
});
|
||
|
||
_service.SaveAccountingBooks(items);
|
||
RefreshItems(null);
|
||
_dialogService.ShowInfo("Запись справочника удалена.");
|
||
}, true);
|
||
}
|
||
|
||
private void EditSelectedItem()
|
||
{
|
||
if (SelectedItem == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var seed = CloneItem(SelectedItem);
|
||
var result = _dialogService.ShowAccountingBookEditDialog(seed, false, Items.ToList());
|
||
if (result == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
RunOperation(delegate
|
||
{
|
||
var items = CloneItems(Items);
|
||
var index = items.FindIndex(delegate(GroupOption item)
|
||
{
|
||
return string.Equals(item.Key, seed.Key, StringComparison.OrdinalIgnoreCase);
|
||
});
|
||
|
||
if (index < 0)
|
||
{
|
||
throw new InvalidOperationException("Не удалось найти книгу учета для обновления.");
|
||
}
|
||
|
||
items[index] = CloneItem(result);
|
||
_service.SaveAccountingBooks(items);
|
||
RefreshItems(result.Key);
|
||
_dialogService.ShowInfo("Запись справочника обновлена.");
|
||
}, true);
|
||
}
|
||
|
||
private bool FilterItems(object item)
|
||
{
|
||
var directoryItem = item as GroupOption;
|
||
if (directoryItem == null)
|
||
{
|
||
return false;
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(SearchText))
|
||
{
|
||
return true;
|
||
}
|
||
|
||
return Contains(directoryItem.Key, SearchText)
|
||
|| Contains(directoryItem.Title, SearchText);
|
||
}
|
||
|
||
private void RaiseCommandStates()
|
||
{
|
||
((RelayCommand)AddCommand).RaiseCanExecuteChanged();
|
||
((RelayCommand)DeleteCommand).RaiseCanExecuteChanged();
|
||
((RelayCommand)EditCommand).RaiseCanExecuteChanged();
|
||
((RelayCommand)RefreshCommand).RaiseCanExecuteChanged();
|
||
}
|
||
|
||
private void RefreshItems(string keyToSelect)
|
||
{
|
||
var items = _service.LoadAccountingBooks();
|
||
var currentKey = string.IsNullOrWhiteSpace(keyToSelect)
|
||
? (SelectedItem == null ? null : SelectedItem.Key)
|
||
: keyToSelect;
|
||
|
||
Items.Clear();
|
||
foreach (var item in items)
|
||
{
|
||
Items.Add(CloneItem(item));
|
||
}
|
||
|
||
ItemsView.Refresh();
|
||
SelectedItem = string.IsNullOrWhiteSpace(currentKey)
|
||
? Items.FirstOrDefault()
|
||
: Items.FirstOrDefault(delegate(GroupOption item)
|
||
{
|
||
return string.Equals(item.Key, currentKey, StringComparison.OrdinalIgnoreCase);
|
||
}) ?? Items.FirstOrDefault();
|
||
UpdateStatus();
|
||
}
|
||
|
||
private void RunOperation(Action action, bool showWarningForInvalidOperation)
|
||
{
|
||
try
|
||
{
|
||
action();
|
||
}
|
||
catch (InvalidOperationException ex)
|
||
{
|
||
if (showWarningForInvalidOperation)
|
||
{
|
||
_dialogService.ShowWarning(ex.Message);
|
||
return;
|
||
}
|
||
|
||
_dialogService.ShowError(ex.Message);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_dialogService.ShowError(ex.Message);
|
||
}
|
||
}
|
||
|
||
private static GroupOption CloneItem(GroupOption item)
|
||
{
|
||
return new GroupOption
|
||
{
|
||
Key = item == null ? string.Empty : item.Key,
|
||
Title = item == null ? string.Empty : item.Title
|
||
};
|
||
}
|
||
|
||
private static List<GroupOption> CloneItems(IEnumerable<GroupOption> items)
|
||
{
|
||
var result = new List<GroupOption>();
|
||
|
||
foreach (var item in items ?? Array.Empty<GroupOption>())
|
||
{
|
||
result.Add(CloneItem(item));
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
private void UpdateStatus()
|
||
{
|
||
var visibleCount = ItemsView.Cast<object>().Count();
|
||
StatusText = string.Format("Всего записей: {0}. По фильтру: {1}.", Items.Count, visibleCount);
|
||
}
|
||
}
|
||
}
|