This commit is contained in:
Курнат Андрей
2026-03-19 23:31:41 +03:00
parent ce3a3f02d2
commit a47a7a5a3b
104 changed files with 21982 additions and 0 deletions

View File

@@ -0,0 +1,294 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Input;
namespace XLAB2
{
internal sealed class SpnmtpDirectoryWindowViewModel : ObservableObject
{
private readonly IDialogService _dialogService;
private readonly PsvDataService _service;
private bool _isBusy;
private string _searchText;
private SpnmtpDirectoryItem _selectedItem;
private string _statusText;
public SpnmtpDirectoryWindowViewModel(PsvDataService service, IDialogService dialogService)
{
_service = service;
_dialogService = dialogService;
Items = new ObservableCollection<SpnmtpDirectoryItem>();
ItemsView = CollectionViewSource.GetDefaultView(Items);
ItemsView.Filter = FilterItems;
AddCommand = new RelayCommand(delegate { AddItemAsync(); }, delegate { return !IsBusy; });
DeleteCommand = new RelayCommand(delegate { DeleteSelectedItemAsync(); }, delegate { return !IsBusy && SelectedItem != null; });
EditCommand = new RelayCommand(delegate { EditSelectedItemAsync(); }, delegate { return !IsBusy && SelectedItem != null; });
RefreshCommand = new RelayCommand(delegate { RefreshAsync(); }, delegate { return !IsBusy; });
UpdateStatus();
}
public ICommand AddCommand { get; private set; }
public ICommand DeleteCommand { get; private set; }
public ICommand EditCommand { get; private set; }
public ObservableCollection<SpnmtpDirectoryItem> Items { get; private set; }
public ICollectionView ItemsView { get; private set; }
public bool IsBusy
{
get { return _isBusy; }
private set
{
if (SetProperty(ref _isBusy, value))
{
RaiseCommandStates();
}
}
}
public ICommand RefreshCommand { get; private set; }
public string SearchText
{
get { return _searchText; }
set
{
if (SetProperty(ref _searchText, value))
{
ItemsView.Refresh();
UpdateStatus();
}
}
}
public SpnmtpDirectoryItem SelectedItem
{
get { return _selectedItem; }
set
{
if (SetProperty(ref _selectedItem, value))
{
RaiseCommandStates();
}
}
}
public string StatusText
{
get { return _statusText; }
private set { SetProperty(ref _statusText, value); }
}
public async Task InitializeAsync()
{
await ExecuteBusyOperationAsync(delegate { return RefreshCoreAsync(null); });
}
private void AddItemAsync()
{
var result = _dialogService.ShowSpnmtpEditDialog(new SpnmtpDirectoryItem(), true, Items.ToList());
if (result == null)
{
return;
}
RunMutationOperation(async delegate
{
var createdId = await Task.Run(delegate { return _service.AddSpnmtpItem(result); });
await RefreshCoreAsync(createdId);
_dialogService.ShowInfo("Запись справочника добавлена.");
});
}
private bool Contains(string source, string searchText)
{
return !string.IsNullOrWhiteSpace(source)
&& source.IndexOf(searchText, StringComparison.OrdinalIgnoreCase) >= 0;
}
private void DeleteSelectedItemAsync()
{
if (SelectedItem == null)
{
return;
}
var selectedItem = SelectedItem;
if (!_dialogService.Confirm(string.Format("Удалить запись \"{0}\"?", selectedItem.Name)))
{
return;
}
RunMutationOperation(async delegate
{
var deleteResult = await Task.Run(delegate { return _service.DeleteSpnmtpItem(selectedItem.Id); });
if (!deleteResult.IsDeleted)
{
_dialogService.ShowWarning(deleteResult.WarningMessage);
return;
}
await RefreshCoreAsync(null);
_dialogService.ShowInfo("Запись справочника удалена.");
});
}
private void EditSelectedItemAsync()
{
if (SelectedItem == null)
{
return;
}
var seed = new SpnmtpDirectoryItem
{
Id = SelectedItem.Id,
Name = SelectedItem.Name,
SpecialName = SelectedItem.SpecialName
};
var result = _dialogService.ShowSpnmtpEditDialog(seed, false, Items.ToList());
if (result == null)
{
return;
}
RunMutationOperation(async delegate
{
await Task.Run(delegate { _service.UpdateSpnmtpItem(result); });
await RefreshCoreAsync(result.Id);
_dialogService.ShowInfo("Запись справочника обновлена.");
});
}
private async Task ExecuteBusyOperationAsync(Func<Task> operation)
{
try
{
IsBusy = true;
await operation();
}
catch (Exception ex)
{
_dialogService.ShowError(ex.Message);
}
finally
{
IsBusy = false;
}
}
private async Task ExecuteMutationOperationAsync(Func<Task> operation)
{
try
{
IsBusy = true;
await operation();
}
catch (InvalidOperationException ex)
{
_dialogService.ShowWarning(ex.Message);
}
catch (Exception ex)
{
_dialogService.ShowError(ex.Message);
}
finally
{
IsBusy = false;
}
}
private bool FilterItems(object item)
{
var directoryItem = item as SpnmtpDirectoryItem;
if (directoryItem == null)
{
return false;
}
if (string.IsNullOrWhiteSpace(SearchText))
{
return true;
}
return Contains(directoryItem.Name, SearchText)
|| Contains(directoryItem.SpecialName, SearchText)
|| directoryItem.Id.ToString().IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
}
private async Task RefreshCoreAsync(int? idToSelect)
{
var items = await _service.LoadSpnmtpItemsAsync();
var currentId = idToSelect ?? (SelectedItem == null ? (int?)null : SelectedItem.Id);
Items.Clear();
foreach (var item in items)
{
Items.Add(item);
}
ItemsView.Refresh();
SelectedItem = currentId.HasValue
? Items.FirstOrDefault(delegate(SpnmtpDirectoryItem item) { return item.Id == currentId.Value; })
: Items.FirstOrDefault();
UpdateStatus();
}
private void RefreshAsync()
{
RunBusyOperation(delegate { return RefreshCoreAsync(null); });
}
private void RaiseCommandStates()
{
((RelayCommand)AddCommand).RaiseCanExecuteChanged();
((RelayCommand)DeleteCommand).RaiseCanExecuteChanged();
((RelayCommand)EditCommand).RaiseCanExecuteChanged();
((RelayCommand)RefreshCommand).RaiseCanExecuteChanged();
}
private async void RunBusyOperation(Func<Task> operation)
{
try
{
await ExecuteBusyOperationAsync(operation);
}
catch (Exception ex)
{
IsBusy = false;
_dialogService.ShowError(ex.Message);
}
}
private async void RunMutationOperation(Func<Task> operation)
{
try
{
await ExecuteMutationOperationAsync(operation);
}
catch (Exception ex)
{
IsBusy = false;
_dialogService.ShowError(ex.Message);
}
}
private void UpdateStatus()
{
var visibleCount = ItemsView.Cast<object>().Count();
StatusText = string.Format("Всего записей: {0}. По фильтру: {1}.", Items.Count, visibleCount);
}
}
}