This commit is contained in:
Курнат Андрей
2026-04-03 21:06:10 +03:00
parent 1b20b39aca
commit a2b4762702
16 changed files with 1170 additions and 33 deletions

View File

@@ -0,0 +1,266 @@
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);
}
}
}