Files
XLAB/XLAB2/AccountingBookDirectoryWindowViewModel.cs
Курнат Андрей a2b4762702 edit
2026-04-03 21:06:10 +03:00

267 lines
8.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}