using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using Pf2e.Database; using Pf2e.Database.Model.Base; using Pf2e.Database.Model.Enum; using Pf2e.Scrapper.WPF.EntityViewer.Stores; using Pf2e.WPF.EntityViewer.Stores; namespace Pf2e.WPF.EntityViewer.ViewModel; internal class EntityListViewModel : ViewModelBase { public Pf2eDbContext Context { get; } public SelectedEntityTypeStore SelectedEntityTypeStore { get; } public SelectedEntityStore SelectedEntityStore { get; } private EntityType? SelectedEntityType => SelectedEntityTypeStore.SelectedEntityType; public Entity? SelectedEntity { get => SelectedEntityStore.SelectedEntity; set => SelectedEntityStore.SelectedEntity = value; } public int Page { get => _page; set { _page = Math.Clamp(value, 1, PageCount); OnPropertyChanged(); OnPropertyChanged(nameof(HasPrevious)); OnPropertyChanged(nameof(HasNext)); Reload(); } } private int _page = 1; public int EntitiesCount { get => _entitiesCount; set { _entitiesCount = value; OnPropertyChanged(); OnPropertyChanged(nameof(PageCount)); OnPropertyChanged(nameof(HasPrevious)); OnPropertyChanged(nameof(HasNext)); } } private int _entitiesCount = 1; public int PerPage { get => _perPage; set { _perPage = value; OnPropertyChanged(); OnPropertyChanged(nameof(PageCount)); Reload(); } } private int _perPage = 30; public string Search { get => _search; set { _search = value; OnPropertyChanged(); Reload(); } } private string _search = ""; public int PageCount => Convert.ToInt32(Math.Ceiling(1.0 * EntitiesCount / PerPage)); public IEnumerable Entities { get => _entities; set { _entities = [.. value]; SelectedEntity = Entities.FirstOrDefault(); OnPropertyChanged(); } } private ObservableCollection _entities = []; public EntityListViewModel( Pf2eDbContext context, SelectedEntityTypeStore selectedEntityTypeStore, SelectedEntityStore selectedEntityStore ) { Context = context; SelectedEntityTypeStore = selectedEntityTypeStore; SelectedEntityStore = selectedEntityStore; SelectedEntityTypeStore.SelectedEntityTypeChanged += SelectedEntityTypeStore_SelectedEntityTypeChanged; } ~EntityListViewModel() { SelectedEntityTypeStore.SelectedEntityTypeChanged -= SelectedEntityTypeStore_SelectedEntityTypeChanged; } private void SelectedEntityTypeStore_SelectedEntityTypeChanged(EntityType? entityType) { if (entityType is null) { Page = 1; EntitiesCount = 1; Entities = []; return; } Page = 1; Reload(); } #region "Методы кнопок" private PageNavigationCommand? _firstPageCommand; public PageNavigationCommand FirstPageCommand { get { return _firstPageCommand ??= new PageNavigationCommand(() => { Page = 1; }); } } private PageNavigationCommand? _previousPageCommand; public PageNavigationCommand PreviousPageCommand { get { return _previousPageCommand ??= new PageNavigationCommand(() => { Page--; }); } } private PageNavigationCommand? _nextPageCommand; public PageNavigationCommand NextPageCommand { get { return _nextPageCommand ??= new PageNavigationCommand(() => { Page++; }); } } private PageNavigationCommand? _lastPageCommand; public PageNavigationCommand LastPageCommand { get { return _lastPageCommand ??= new PageNavigationCommand(() => { Page = PageCount; }); } } public bool HasPrevious => Page != 1; public bool HasNext => Page != PageCount; #endregion #region "Запросы" /// /// Выполняет запрос к базе данных и обрабатывает результаты. /// public void Reload() { Pf2eDbContext dbContext = new(); IQueryable query = Search == "" ? dbContext.Entities.Where(e => e.Type == SelectedEntityType) : // ReSharper disable once EntityFramework.UnsupportedServerSideFunctionCall dbContext.Entities.Where(e => e.Type == SelectedEntityType && Pf2eDbContext.LocaleSearch(e.Name, Search) ); EntitiesCount = query.Count(); Entities = [.. query.OrderBy(e => e.Id).Skip((Page - 1) * PerPage).Take(PerPage).ToList()]; } #endregion } /// /// Команда для навигации по страницам. /// /// Действие, выполняемое при выполнении команды. public class PageNavigationCommand(Action action) : System.Windows.Input.ICommand { /// /// Действие, выполняемое при выполнении команды. /// public Action Action { get; } = action; /// /// Событие, вызываемое при изменении возможности выполнения команды. /// public event EventHandler? CanExecuteChanged; /// /// Проверяет, может ли команда быть выполнена с указанным параметром. /// /// Параметр команды. /// Флаг, указывающий, может ли команда быть выполнена. public bool CanExecute(object? parameter) { return true; } /// /// Выполняет команду с указанным параметром. /// /// Параметр команды. public void Execute(object? parameter) { Action.Invoke(); } }