edit
This commit is contained in:
476
XLAB2/FrpdDirectoryWindowViewModel.cs
Normal file
476
XLAB2/FrpdDirectoryWindowViewModel.cs
Normal file
@@ -0,0 +1,476 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace XLAB2
|
||||
{
|
||||
internal sealed class FrpdDirectoryWindowViewModel : ObservableObject
|
||||
{
|
||||
private readonly IFrpdDirectoryDialogService _dialogService;
|
||||
private readonly FrpdDirectoryService _service;
|
||||
private List<FrpdDirectoryItem> _frpdCache;
|
||||
private bool _isBusy;
|
||||
private string _searchText;
|
||||
private FrpdDirectoryItem _selectedFrpd;
|
||||
private FrpdvdDirectoryItem _selectedFrpdvd;
|
||||
private string _statusText;
|
||||
|
||||
public FrpdDirectoryWindowViewModel(FrpdDirectoryService service, IFrpdDirectoryDialogService dialogService)
|
||||
{
|
||||
_service = service;
|
||||
_dialogService = dialogService;
|
||||
_frpdCache = new List<FrpdDirectoryItem>();
|
||||
|
||||
FrpdItems = new ObservableCollection<FrpdDirectoryItem>();
|
||||
FrpdvdItems = new ObservableCollection<FrpdvdDirectoryItem>();
|
||||
|
||||
AddFrpdCommand = new RelayCommand(delegate { AddFrpdAsync(); }, delegate { return !IsBusy; });
|
||||
EditFrpdCommand = new RelayCommand(delegate { EditFrpdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
||||
DeleteFrpdCommand = new RelayCommand(delegate { DeleteFrpdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
||||
AddFrpdvdCommand = new RelayCommand(delegate { AddFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpd != null; });
|
||||
EditFrpdvdCommand = new RelayCommand(delegate { EditFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpdvd != null; });
|
||||
DeleteFrpdvdCommand = new RelayCommand(delegate { DeleteFrpdvdAsync(); }, delegate { return !IsBusy && SelectedFrpdvd != null; });
|
||||
RefreshCommand = new RelayCommand(delegate { RefreshAsync(); }, delegate { return !IsBusy; });
|
||||
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
public ICommand AddFrpdCommand { get; private set; }
|
||||
public ICommand AddFrpdvdCommand { get; private set; }
|
||||
public ICommand DeleteFrpdCommand { get; private set; }
|
||||
public ICommand DeleteFrpdvdCommand { get; private set; }
|
||||
public ICommand EditFrpdCommand { get; private set; }
|
||||
public ICommand EditFrpdvdCommand { get; private set; }
|
||||
public ObservableCollection<FrpdDirectoryItem> FrpdItems { get; private set; }
|
||||
public ObservableCollection<FrpdvdDirectoryItem> FrpdvdItems { get; private set; }
|
||||
public ICommand RefreshCommand { get; private set; }
|
||||
|
||||
public bool IsBusy
|
||||
{
|
||||
get { return _isBusy; }
|
||||
private set
|
||||
{
|
||||
if (SetProperty(ref _isBusy, value))
|
||||
{
|
||||
RaiseCommandStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get { return _searchText; }
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _searchText, value))
|
||||
{
|
||||
ApplySearchFilter();
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FrpdDirectoryItem SelectedFrpd
|
||||
{
|
||||
get { return _selectedFrpd; }
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedFrpd, value))
|
||||
{
|
||||
RaiseCommandStates();
|
||||
LoadFrpdvdForSelection();
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public FrpdvdDirectoryItem SelectedFrpdvd
|
||||
{
|
||||
get { return _selectedFrpdvd; }
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _selectedFrpdvd, value))
|
||||
{
|
||||
RaiseCommandStates();
|
||||
UpdateStatus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string StatusText
|
||||
{
|
||||
get { return _statusText; }
|
||||
private set { SetProperty(ref _statusText, value); }
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await ExecuteBusyOperationAsync(async delegate { await RefreshFrpdCoreAsync(null, null); });
|
||||
}
|
||||
|
||||
private void AddFrpdAsync()
|
||||
{
|
||||
var result = _dialogService.ShowFrpdEditDialog(new FrpdDirectoryItem(), true, _frpdCache.ToList(), _service);
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
var createdId = await Task.Run(delegate { return _service.AddFrpdItem(result); });
|
||||
await RefreshFrpdCoreAsync(createdId, null);
|
||||
_dialogService.ShowInfo("Запись FRPD добавлена.");
|
||||
});
|
||||
}
|
||||
|
||||
private void AddFrpdvdAsync()
|
||||
{
|
||||
if (SelectedFrpd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = _dialogService.ShowFrpdvdEditDialog(new FrpdvdDirectoryItem { FrpdId = SelectedFrpd.Id }, true, FrpdvdItems.ToList(), _service);
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
var createdId = await Task.Run(delegate { return _service.AddFrpdvdItem(result); });
|
||||
await RefreshFrpdCoreAsync(result.FrpdId, createdId);
|
||||
_dialogService.ShowInfo("Запись FRPDVD добавлена.");
|
||||
});
|
||||
}
|
||||
|
||||
private void ApplyFrpdFilter(int? preferredId)
|
||||
{
|
||||
var filteredItems = _frpdCache.Where(delegate(FrpdDirectoryItem item) { return MatchesSearch(item); }).ToList();
|
||||
FrpdItems.Clear();
|
||||
foreach (var item in filteredItems)
|
||||
{
|
||||
FrpdItems.Add(item);
|
||||
}
|
||||
|
||||
SelectedFrpd = preferredId.HasValue
|
||||
? FrpdItems.FirstOrDefault(delegate(FrpdDirectoryItem item) { return item.Id == preferredId.Value; })
|
||||
: FrpdItems.FirstOrDefault();
|
||||
}
|
||||
|
||||
private void ApplySearchFilter()
|
||||
{
|
||||
if (!IsBusy)
|
||||
{
|
||||
ApplyFrpdFilter(SelectedFrpd == null ? (int?)null : SelectedFrpd.Id);
|
||||
}
|
||||
}
|
||||
|
||||
private static FrpdDirectoryItem CloneFrpd(FrpdDirectoryItem source)
|
||||
{
|
||||
return new FrpdDirectoryItem
|
||||
{
|
||||
CreatedOn = source.CreatedOn,
|
||||
Guid = source.Guid,
|
||||
Id = source.Id,
|
||||
LiquidatedOn = source.LiquidatedOn,
|
||||
LocalCode = source.LocalCode,
|
||||
Name = source.Name,
|
||||
ParentId = source.ParentId,
|
||||
ParentName = source.ParentName
|
||||
};
|
||||
}
|
||||
|
||||
private static FrpdvdDirectoryItem CloneFrpdvd(FrpdvdDirectoryItem source)
|
||||
{
|
||||
return new FrpdvdDirectoryItem
|
||||
{
|
||||
ActivityId = source.ActivityId,
|
||||
ActivityName = source.ActivityName,
|
||||
FrpdId = source.FrpdId,
|
||||
Id = source.Id
|
||||
};
|
||||
}
|
||||
|
||||
private void DeleteFrpdAsync()
|
||||
{
|
||||
if (SelectedFrpd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = SelectedFrpd;
|
||||
if (!_dialogService.Confirm(string.Format("Удалить организацию/подразделение \"{0}\"?", selected.Name)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
var result = await Task.Run(delegate { return _service.DeleteFrpdItem(selected.Id); });
|
||||
if (!result.IsDeleted)
|
||||
{
|
||||
_dialogService.ShowWarning(result.WarningMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
await RefreshFrpdCoreAsync(null, null);
|
||||
_dialogService.ShowInfo("Запись удалена.");
|
||||
});
|
||||
}
|
||||
|
||||
private void DeleteFrpdvdAsync()
|
||||
{
|
||||
if (SelectedFrpdvd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = SelectedFrpdvd;
|
||||
if (!_dialogService.Confirm(string.Format("Удалить вид деятельности \"{0}\"?", selected.ActivityName)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
var result = await Task.Run(delegate { return _service.DeleteFrpdvdItem(selected.Id); });
|
||||
if (!result.IsDeleted)
|
||||
{
|
||||
_dialogService.ShowWarning(result.WarningMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
await RefreshFrpdCoreAsync(selected.FrpdId, null);
|
||||
_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 void EditFrpdAsync()
|
||||
{
|
||||
if (SelectedFrpd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = _dialogService.ShowFrpdEditDialog(CloneFrpd(SelectedFrpd), false, _frpdCache.ToList(), _service);
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
await Task.Run(delegate { _service.UpdateFrpdItem(result); });
|
||||
await RefreshFrpdCoreAsync(result.Id, SelectedFrpdvd == null ? (int?)null : SelectedFrpdvd.Id);
|
||||
_dialogService.ShowInfo("Запись обновлена.");
|
||||
});
|
||||
}
|
||||
|
||||
private void EditFrpdvdAsync()
|
||||
{
|
||||
if (SelectedFrpdvd == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = _dialogService.ShowFrpdvdEditDialog(CloneFrpdvd(SelectedFrpdvd), false, FrpdvdItems.ToList(), _service);
|
||||
if (result == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RunMutationOperation(async delegate
|
||||
{
|
||||
await Task.Run(delegate { _service.UpdateFrpdvdItem(result); });
|
||||
await RefreshFrpdCoreAsync(result.FrpdId, result.Id);
|
||||
_dialogService.ShowInfo("Запись обновлена.");
|
||||
});
|
||||
}
|
||||
|
||||
private string[] GetSearchTokens()
|
||||
{
|
||||
return (SearchText ?? string.Empty)
|
||||
.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(delegate(string token) { return token.Trim().ToUpperInvariant(); })
|
||||
.Where(delegate(string token) { return token.Length > 0; })
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private void LoadFrpdvdForSelection()
|
||||
{
|
||||
if (!IsBusy)
|
||||
{
|
||||
RunBusyOperation(async delegate
|
||||
{
|
||||
if (SelectedFrpd == null)
|
||||
{
|
||||
FrpdvdItems.Clear();
|
||||
SelectedFrpdvd = null;
|
||||
UpdateStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
await RefreshFrpdvdCoreAsync(SelectedFrpd.Id, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private bool MatchesSearch(FrpdDirectoryItem item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var tokens = GetSearchTokens();
|
||||
if (tokens.Length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var haystack = string.Join(
|
||||
" ",
|
||||
new[]
|
||||
{
|
||||
item.Id.ToString(),
|
||||
item.Name,
|
||||
item.ParentName,
|
||||
item.LocalCode,
|
||||
item.Guid,
|
||||
item.ActivityNames
|
||||
}
|
||||
.Where(delegate(string value) { return !string.IsNullOrWhiteSpace(value); }))
|
||||
.ToUpperInvariant();
|
||||
return tokens.All(delegate(string token) { return haystack.IndexOf(token, StringComparison.Ordinal) >= 0; });
|
||||
}
|
||||
|
||||
private async Task RefreshFrpdCoreAsync(int? frpdIdToSelect, int? frpdvdIdToSelect)
|
||||
{
|
||||
var currentFrpdId = SelectedFrpd == null ? (int?)null : SelectedFrpd.Id;
|
||||
_frpdCache = (await Task.Run(delegate { return _service.LoadFrpdItems(); })).ToList();
|
||||
|
||||
ApplyFrpdFilter(frpdIdToSelect.HasValue ? frpdIdToSelect : currentFrpdId);
|
||||
if (SelectedFrpd == null)
|
||||
{
|
||||
FrpdvdItems.Clear();
|
||||
SelectedFrpdvd = null;
|
||||
UpdateStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
await RefreshFrpdvdCoreAsync(SelectedFrpd.Id, frpdvdIdToSelect);
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private async Task RefreshFrpdvdCoreAsync(int frpdId, int? frpdvdIdToSelect)
|
||||
{
|
||||
var items = await Task.Run(delegate { return _service.LoadFrpdvdItems(frpdId); });
|
||||
FrpdvdItems.Clear();
|
||||
foreach (var item in items)
|
||||
{
|
||||
FrpdvdItems.Add(item);
|
||||
}
|
||||
|
||||
SelectedFrpdvd = frpdvdIdToSelect.HasValue
|
||||
? FrpdvdItems.FirstOrDefault(delegate(FrpdvdDirectoryItem item) { return item.Id == frpdvdIdToSelect.Value; })
|
||||
: FrpdvdItems.FirstOrDefault();
|
||||
UpdateStatus();
|
||||
}
|
||||
|
||||
private void RaiseCommandStates()
|
||||
{
|
||||
((RelayCommand)AddFrpdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)EditFrpdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)DeleteFrpdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)AddFrpdvdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)EditFrpdvdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)DeleteFrpdvdCommand).RaiseCanExecuteChanged();
|
||||
((RelayCommand)RefreshCommand).RaiseCanExecuteChanged();
|
||||
}
|
||||
|
||||
private void RefreshAsync()
|
||||
{
|
||||
RunBusyOperation(async delegate { await RefreshFrpdCoreAsync(SelectedFrpd == null ? (int?)null : SelectedFrpd.Id, SelectedFrpdvd == null ? (int?)null : SelectedFrpdvd.Id); });
|
||||
}
|
||||
|
||||
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 searchText = string.IsNullOrWhiteSpace(SearchText) ? null : SearchText.Trim();
|
||||
StatusText = string.Format(
|
||||
"{0}Подразделений: {1}/{2}. Видов деятельности: {3}.",
|
||||
string.IsNullOrWhiteSpace(searchText) ? string.Empty : string.Format("Поиск: \"{0}\". ", searchText),
|
||||
FrpdItems.Count,
|
||||
_frpdCache.Count,
|
||||
FrpdvdItems.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user