/
hlebusheck
/
notes
Обзор
Документация
Войти
/
hlebusheck
/
notes
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
Notes.Wpf/MainWindow.xaml.cs
508 строк
16 KB
Hlebusheck
Исправлены вызовы асинхронных функций
20 апр 2024, 16:12
20 апр 2024, 16:12
f6f8238
Код
Авторство
О чём код?
using Notes.Model; using Notes.Controls.Commands; using Notes.Repository; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Data; using System.Windows.Input; using Notes.Wpf.Controls; using System.Windows.Media; using System.Configuration; namespace Notes { public enum RemoveOption { WithoutRemoved = 0, All = 1, OnlyRemoved = 2 } public enum SearchMode { All, Headers, Contents } public enum SortBy { Created, Updated, Header } public partial class MainWindow : Window, INotifyPropertyChanged { private readonly IMemoRepository _repository; private Memo? _currentItem; private string _filterText = string.Empty; private RemoveOption _removeOption; private bool _fullCreatedDate = false; private bool _fullUpdatedDate = false; private SearchMode _searchMode; private SortBy _sortBy; private ListSortDirection _sortDirection; private ConfigurationWindow? _configurationWindow; public MainWindow(IMemoRepository repository) { var config = Wpf.Properties.Settings.Default.FilterConfig; if (config == null) { config = Wpf.Properties.Settings.Default.FilterConfig = new FilterConfig(); Wpf.Properties.Settings.Default.Save(); } _sortBy = config.SortBy; _sortDirection = config.SortDirection; _searchMode = config.SearchMode; _removeOption = config.RemoveOption; InitializeComponent(); SaveCommand = new RelayCommand(async (_) => await SaveCurrentItem(), (_) => CurrentItem != null); DataContext = this; _repository = repository; } public ObservableCollection<Memo> Items { get; } = []; public Memo? CurrentItem { get => _currentItem; set { _currentItem = value; OnPropertyChanged(nameof(CurrentItem)); } } public string FilterText { get => _filterText; set { _filterText = value; OnPropertyChanged(nameof(FilterText)); RefreshCollectionView(); } } public ICommand SaveCommand { get; set; } public RemoveOption RemoveOption { get => _removeOption; set { _removeOption = value; RefreshCollectionView(); } } public bool FullCreatedDate { get => _fullCreatedDate; set { if (_fullCreatedDate != value) { _fullCreatedDate = value; OnPropertyChanged(nameof(FullCreatedDate)); } } } public bool FullUpdatedDate { get => _fullUpdatedDate; set { if (_fullUpdatedDate != value) { _fullUpdatedDate = value; OnPropertyChanged(nameof(FullUpdatedDate)); } } } public SearchMode SearchMode { get => _searchMode; set { _searchMode = value; RefreshCollectionView(); } } public SortBy SortBy { get => _sortBy; set { _sortBy = value; UpdateSort(); } } public ListSortDirection SortDirection { get => _sortDirection; set { _sortDirection = value; UpdateSort(); } } private async Task Load() { Items.Clear(); var items = await _repository.Get(); foreach (var item in items) Items.Add(item); } private void AddClick(object sender, RoutedEventArgs e) => Add(); private async void RemoveClick(object sender, RoutedEventArgs e) => await RemoveCurrentItem(); private async void RecoverClick(object sender, RoutedEventArgs e) => await RecoverCurrentItem(); private async void DeleteClick(object sender, RoutedEventArgs e) => await DeleteCurrentItem(); private void RefreshClick(object sender, RoutedEventArgs e) => Refresh(); private void RefreshViewClick(object sender, RoutedEventArgs e) => RefreshCollectionView(); private void CloseFilterClick(object sender, RoutedEventArgs e) => ShowFilter.IsChecked = false; private void OpenConfigurationClick(object sender, RoutedEventArgs e) { _configurationWindow ??= new ConfigurationWindow(_repository) { Owner = this }; _configurationWindow.Closed += (_, _) => _configurationWindow = null; _configurationWindow.Show(); _configurationWindow.Focus(); } private async void SaveItemEvent(object sender, KeyboardFocusChangedEventArgs e) => await SaveCurrentItem(); public async void Refresh() { CurrentItem = null; await Load(); } private void Add() { CurrentItem = new Memo { Header = FilterText }; if (string.IsNullOrEmpty(FilterText)) Header.Focus(); else BodyTextBox.Focus(); FilterText = string.Empty; } private async Task SaveCurrentItem() { if (CurrentItem == null) return; if (CurrentItem.New && (!string.IsNullOrEmpty(CurrentItem.Header) || !string.IsNullOrEmpty(CurrentItem.Body))) { _ = await _repository.Insert(CurrentItem); CurrentItem.ApplyChanges(); Items.Add(CurrentItem); } else if (CurrentItem.HasChanges || CurrentItem.Options.HasChanges) { _ = await _repository.Update(CurrentItem); CurrentItem.ApplyChanges(); } OnPropertyChanged(nameof(CurrentItem)); } private async Task RemoveCurrentItem() { if (CurrentItem == null) return; if (CurrentItem.Id == 0) CurrentItem = null; else { if (CustomMessageBox.Show( this, $"Remove {CurrentItem.Header}?", "Warning", "\u0028", (SolidColorBrush)Application.Current.FindResource("WarningSolidBrush"), MessageBoxButton.YesNo ) == MessageBoxResult.Yes) _ = await _repository.Remove(CurrentItem); else return; } await Load(); } private async Task RecoverCurrentItem() { if (CurrentItem == null) return; if (CurrentItem.Id == 0) CurrentItem = null; else await _repository.Recover(CurrentItem); await Load(); } private async Task DeleteCurrentItem() { if (CurrentItem == null) return; if (CurrentItem.Id == 0) CurrentItem = null; else { if (CustomMessageBox.Show( this, $"Delete {CurrentItem.Header}?", "Warning", "\u0045", (SolidColorBrush)Application.Current.FindResource("ErrorSolidBrush"), MessageBoxButton.YesNo ) == MessageBoxResult.Yes) _ = await _repository.Delete(CurrentItem); else return; } await Load(); } #region INotifyPropertyChanged public event PropertyChangedEventHandler? PropertyChanged; public void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); #endregion INotifyPropertyChanged private async void WindowLoaded(object sender, RoutedEventArgs e) { var collectionView = CollectionViewSource.GetDefaultView(MemoList.ItemsSource); collectionView.Filter += item => { if (item is not Memo memo) return false; if ((string.IsNullOrEmpty(FilterText) || (SearchMode != SearchMode.Contents && DeepContains(memo.Header, FilterText)) || (SearchMode != SearchMode.Headers && memo.Body.Contains(FilterText, StringComparison.OrdinalIgnoreCase))) && (RemoveOption == RemoveOption.All || (RemoveOption == RemoveOption.WithoutRemoved && memo.Removed == false) || (RemoveOption == RemoveOption.OnlyRemoved && memo.Removed == true))) return true; return false; }; UpdateSort(); MoveFocus(new TraversalRequest(FocusNavigationDirection.First)); await Load(); } private void UpdateSort() => UpdateSort(true); private void UpdateSort(bool refreshView) { var collectionView = CollectionViewSource.GetDefaultView(MemoList.ItemsSource); collectionView.SortDescriptions.Clear(); collectionView.SortDescriptions.Add(new SortDescription(nameof(Memo.Options), ListSortDirection.Descending)); collectionView.SortDescriptions.Add(new SortDescription(SortBy switch { SortBy.Created => nameof(Memo.InsertedDate), SortBy.Updated => nameof(Memo.UpdatedDate), SortBy.Header => nameof(Memo.Header), _ => nameof(Memo.InsertedDate) }, SortDirection)); if (refreshView) RefreshCollectionView(); } private void RefreshCollectionView() { var collectionView = CollectionViewSource.GetDefaultView(MemoList.ItemsSource); collectionView.Refresh(); } private void ClearFilter(object sender, RoutedEventArgs e) => FilterText = string.Empty; private bool DeepContains(string content, string search) { if (content.Contains(search, StringComparison.OrdinalIgnoreCase) || content.Contains(Translate(search), StringComparison.OrdinalIgnoreCase)) return true; return false; } private readonly Dictionary<char, char> _dictionary = new() { { '`', 'ё' }, { '~', 'ё' }, { 'q', 'й' }, { 'w', 'ц' }, { 'e', 'у' }, { 'r', 'к' }, { 't', 'е' }, { 'y', 'н' }, { 'u', 'г' }, { 'i', 'ш' }, { 'o', 'щ' }, { 'p', 'з' }, { '[', 'х' }, { '{', 'х' }, { ']', 'ъ' }, { '}', 'ъ' }, { 'a', 'ф' }, { 's', 'ы' }, { 'd', 'в' }, { 'f', 'а' }, { 'g', 'п' }, { 'h', 'р' }, { 'j', 'о' }, { 'k', 'л' }, { 'l', 'д' }, { ';', 'ж' }, { ':', 'ж' }, { '\'', 'э' }, { '\"', 'э' }, { 'z', 'я' }, { 'x', 'ч' }, { 'c', 'с' }, { 'v', 'м' }, { 'b', 'и' }, { 'n', 'т' }, { 'm', 'ь' }, { ',', 'б' }, { '<', 'б' }, { '.', 'ю' }, { '>', 'ю' }, { 'й', 'q' }, { 'ц', 'w' }, { 'у', 'e' }, { 'к', 'r' }, { 'е', 't' }, { 'н', 'y' }, { 'г', 'u' }, { 'ш', 'i' }, { 'щ', 'o' }, { 'з', 'p' }, { 'ф', 'a' }, { 'ы', 's' }, { 'в', 'd' }, { 'а', 'f' }, { 'п', 'g' }, { 'р', 'h' }, { 'о', 'j' }, { 'л', 'k' }, { 'д', 'l' }, { 'я', 'z' }, { 'ч', 'x' }, { 'с', 'c' }, { 'м', 'v' }, { 'и', 'b' }, { 'т', 'n' }, { 'ь', 'm' } }; private string Translate(string input) { var result = new StringBuilder(); foreach (char symbol in input.ToLower()) { char newSymbol = symbol; try { newSymbol = _dictionary[symbol]; } catch { } result.Append(newSymbol); } return result.ToString(); } private void CreatedDateChangeMode(object sender, MouseButtonEventArgs e) { FullCreatedDate = !FullCreatedDate; if(FullCreatedDate) { var binding = ShortInsertedDateTextBlock.GetBindingExpression(VisibilityProperty); var bindingCopy = new Binding(binding.ParentBinding.Path.Path) { Converter = binding.ParentBinding.Converter, ConverterParameter = binding.ParentBinding.ConverterParameter, Mode = binding.ParentBinding.Mode }; FullInsertedDateTextBlock.SetBinding(VisibilityProperty, bindingCopy); } else { FullInsertedDateTextBlock.Visibility = Visibility.Collapsed; } } private void UpdateDateChangeMode(object sender, MouseButtonEventArgs e) { FullUpdatedDate = !FullUpdatedDate; if (FullUpdatedDate) { var binding = ShortUpdatedDateTextBlock.GetBindingExpression(VisibilityProperty); var bindingCopy = new Binding(binding.ParentBinding.Path.Path) { Converter = binding.ParentBinding.Converter, ConverterParameter = binding.ParentBinding.ConverterParameter, Mode = binding.ParentBinding.Mode }; FullUpdatedDateTextBlock.SetBinding(VisibilityProperty, bindingCopy); } else { FullUpdatedDateTextBlock.Visibility = Visibility.Collapsed; } } private void WindowClosing(object sender, CancelEventArgs e) { var config = new FilterConfig { SortBy = SortBy, SortDirection = SortDirection, SearchMode = SearchMode, RemoveOption = RemoveOption }; Wpf.Properties.Settings.Default.FilterConfig = config; Wpf.Properties.Settings.Default.Save(); } } [SettingsSerializeAs(SettingsSerializeAs.Xml)] public class FilterConfig { public SortBy SortBy { get; set; } = SortBy.Created; public ListSortDirection SortDirection { get; set; } = ListSortDirection.Descending; public SearchMode SearchMode { get; set; } = SearchMode.All; public RemoveOption RemoveOption { get; set; } = RemoveOption.WithoutRemoved; } }