From be0e161fe630d757d525848e5ae3084ba0e5ee0c Mon Sep 17 00:00:00 2001 From: David Sungaila Date: Wed, 2 Oct 2024 19:49:20 +0200 Subject: [PATCH] Change from DataGrid to DataTable --- nuget.config | 3 +- src/Extensions/HackedCollectionView.Defer.cs | 55 -- src/Extensions/HackedCollectionView.Events.cs | 62 -- src/Extensions/HackedCollectionView.cs | 815 ------------------ src/Extensions/VectorChangedEventArgs.cs | 38 - src/Extensions/WindowExtensions.cs | 32 - src/SUBSTitute.csproj | 3 +- src/Strings/de-de/Resources.resw | 8 +- src/Strings/en-us/Resources.resw | 8 +- src/ViewModels/MappingViewModel.cs | 8 - src/Views/GridView.xaml | 2 +- src/Views/GridView.xaml.cs | 3 + src/Views/ListView.xaml | 145 ++-- src/Views/ListView.xaml.cs | 44 +- src/Views/MappingView.xaml | 18 +- src/Views/MappingView.xaml.cs | 3 + src/Views/RemoveDriveView.xaml | 2 +- 17 files changed, 102 insertions(+), 1147 deletions(-) delete mode 100644 src/Extensions/HackedCollectionView.Defer.cs delete mode 100644 src/Extensions/HackedCollectionView.Events.cs delete mode 100644 src/Extensions/HackedCollectionView.cs delete mode 100644 src/Extensions/VectorChangedEventArgs.cs delete mode 100644 src/Extensions/WindowExtensions.cs diff --git a/nuget.config b/nuget.config index 3121ad7..7e59a38 100644 --- a/nuget.config +++ b/nuget.config @@ -2,6 +2,7 @@ - + + \ No newline at end of file diff --git a/src/Extensions/HackedCollectionView.Defer.cs b/src/Extensions/HackedCollectionView.Defer.cs deleted file mode 100644 index 73504fc..0000000 --- a/src/Extensions/HackedCollectionView.Defer.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; - -namespace Sungaila.SUBSTitute.Extensions; - -/// -/// A collection view implementation that supports filtering, grouping, sorting and incremental loading -/// -public partial class HackedCollectionView -{ - /// - /// Stops refreshing until it is disposed - /// - /// An disposable object - public IDisposable DeferRefresh() - { - return new NotificationDeferrer(this); - } - - /// - /// Notification deferrer helper class - /// - public partial class NotificationDeferrer : IDisposable - { - private readonly HackedCollectionView _acvs; - private readonly object _currentItem; - - /// - /// Initializes a new instance of the class. - /// - /// Source ACVS - public NotificationDeferrer(HackedCollectionView acvs) - { - _acvs = acvs; - _currentItem = _acvs.CurrentItem; - _acvs._deferCounter++; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - /// 2 -#pragma warning disable CA1816 - public void Dispose() -#pragma warning restore CA1816 - { - _acvs.MoveCurrentTo(_currentItem); - _acvs._deferCounter--; - _acvs.Refresh(); - } - } -} \ No newline at end of file diff --git a/src/Extensions/HackedCollectionView.Events.cs b/src/Extensions/HackedCollectionView.Events.cs deleted file mode 100644 index 11c3a4b..0000000 --- a/src/Extensions/HackedCollectionView.Events.cs +++ /dev/null @@ -1,62 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Microsoft.UI.Xaml.Data; -using Windows.Foundation.Collections; - -namespace Sungaila.SUBSTitute.Extensions; - -/// -/// A collection view implementation that supports filtering, grouping, sorting and incremental loading -/// -public partial class HackedCollectionView -{ - /// - /// Currently selected item changing event - /// - /// event args - private void OnCurrentChanging(CurrentChangingEventArgs e) - { - if (_deferCounter > 0) - { - return; - } - - CurrentChanging?.Invoke(this, e); - } - - /// - /// Currently selected item changed event - /// - /// event args - private void OnCurrentChanged(object e) - { - if (_deferCounter > 0) - { - return; - } - - CurrentChanged?.Invoke(this, e); - - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(CurrentItem)); - } - - /// - /// Vector changed event - /// - /// event args - private void OnVectorChanged(IVectorChangedEventArgs e) - { - if (_deferCounter > 0) - { - return; - } - - VectorChanged?.Invoke(this, e); - - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(Count)); - } -} \ No newline at end of file diff --git a/src/Extensions/HackedCollectionView.cs b/src/Extensions/HackedCollectionView.cs deleted file mode 100644 index 8a2be43..0000000 --- a/src/Extensions/HackedCollectionView.cs +++ /dev/null @@ -1,815 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using CommunityToolkit.WinUI.Collections; -using CommunityToolkit.WinUI.Helpers; -using Microsoft.UI.Xaml.Data; -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Linq; -using System.Reflection; -using System.Runtime.CompilerServices; -using Windows.Foundation; -using Windows.Foundation.Collections; - -namespace Sungaila.SUBSTitute.Extensions; - -/// -/// A collection view implementation that supports filtering, sorting and incremental loading -/// -[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("Item sorting uses reflection to get property types and may not be AOT compatible.")] -public partial class HackedCollectionView : IAdvancedCollectionView, INotifyPropertyChanged, ISupportIncrementalLoading, IComparer -{ - private readonly List _view; - - private readonly ObservableCollection _sortDescriptions; - - private readonly Dictionary _sortProperties; - - private readonly bool _liveShapingEnabled; - - private readonly HashSet _observedFilterProperties = []; - - private IList _source; - - private Predicate _filter; - private int _deferCounter; - - private WeakEventListener _sourceWeakEventListener; - - /// - /// Initializes a new instance of the class. - /// - public HackedCollectionView() - : this(new List(0)) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// source IEnumerable - /// Denotes whether or not this ACV should re-filter/re-sort if a PropertyChanged is raised for an observed property. -#pragma warning disable CS8769 -#pragma warning disable CS8622 -#pragma warning disable CS8600 -#pragma warning disable CS8601 -#pragma warning disable CS8604 -#pragma warning disable CS8603 // Possible null reference return. -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. - public HackedCollectionView(IList source, bool isLiveShaping = false) - { - _liveShapingEnabled = isLiveShaping; - _view = []; - _sortDescriptions = []; - _sortDescriptions.CollectionChanged += SortDescriptions_CollectionChanged; - _sortProperties = []; - Source = source; - } - - /// - /// Gets or sets the source - /// - public IList Source - { - get - { - return _source; - } - - set - { - // ReSharper disable once PossibleUnintendedReferenceComparison - if (_source == value) - { - return; - } - - if (_source != null) - { - DetachPropertyChangedHandler(_source); - } - - _source = value; - AttachPropertyChangedHandler(_source); - - _sourceWeakEventListener?.Detach(); - - if (_source is INotifyCollectionChanged sourceNcc) - { - _sourceWeakEventListener = - new WeakEventListener(this) - { - // Call the actual collection changed event - OnEventAction = (source, changed, arg3) => SourceNcc_CollectionChanged(source, arg3), - - // The source doesn't exist anymore - OnDetachAction = (listener) => sourceNcc.CollectionChanged -= _sourceWeakEventListener!.OnEvent - }; - sourceNcc.CollectionChanged += _sourceWeakEventListener.OnEvent; - } - - HandleSourceChanged(); - OnPropertyChanged(); - } - } - - /// - /// Manually refresh the view - /// - public void Refresh() - { - HandleSourceChanged(); - } - - /// - public void RefreshFilter() - { - HandleFilterChanged(); - } - - /// - public void RefreshSorting() - { - HandleSortChanged(); - } - - /// - public IEnumerator GetEnumerator() => _view.GetEnumerator(); - - /// - IEnumerator IEnumerable.GetEnumerator() => _view.GetEnumerator(); - - /// - public void Add(object item) - { - if (IsReadOnly) - { - throw new NotSupportedException("Collection is read-only."); - } - - _source.Add(item); - } - - /// - public void Clear() - { - if (IsReadOnly) - { - throw new NotSupportedException("Collection is read-only."); - } - - _source.Clear(); - } - - /// - public bool Contains(object item) => _view.Contains(item); - - /// - public void CopyTo(object[] array, int arrayIndex) => _view.CopyTo(array, arrayIndex); - - /// - public bool Remove(object item) - { - if (IsReadOnly) - { - throw new NotSupportedException("Collection is read-only."); - } - - _source.Remove(item); - return true; - } - - /// - public int Count => _view.Count; - - /// - public bool IsReadOnly => _source == null || _source.IsReadOnly; - - /// - public int IndexOf(object item) => _view.IndexOf(item); - - /// - public void Insert(int index, object item) - { - if (IsReadOnly) - { - throw new NotSupportedException("Collection is read-only."); - } - - _source.Insert(index, item); - } - - /// - /// Removes the item at the specified index. - /// - /// The zero-based index of the item to remove. is not a valid index in the .The is read-only. - public void RemoveAt(int index) => Remove(_view[index]); - - /// - /// Gets or sets the element at the specified index. - /// - /// - /// The element at the specified index. - /// - /// The zero-based index of the element to get or set. is not a valid index in the .The property is set and the is read-only. - public object this[int index] - { - get { return _view[index]; } - set { _view[index] = value; } - } - - /// - /// Occurs when the vector changes. - /// - public event Windows.Foundation.Collections.VectorChangedEventHandler VectorChanged; - - /// - /// Move current index to item - /// - /// item - /// success of operation - public bool MoveCurrentTo(object item) => item == CurrentItem || MoveCurrentToIndex(IndexOf(item)); - - /// - /// Moves selected item to position - /// - /// index - /// success of operation - public bool MoveCurrentToPosition(int index) => MoveCurrentToIndex(index); - - /// - /// Move current item to first item - /// - /// success of operation - public bool MoveCurrentToFirst() => MoveCurrentToIndex(0); - - /// - /// Move current item to last item - /// - /// success of operation - public bool MoveCurrentToLast() => MoveCurrentToIndex(_view.Count - 1); - - /// - /// Move current item to next item - /// - /// success of operation - public bool MoveCurrentToNext() => MoveCurrentToIndex(CurrentPosition + 1); - - /// - /// Move current item to previous item - /// - /// success of operation - public bool MoveCurrentToPrevious() => MoveCurrentToIndex(CurrentPosition - 1); - - /// - /// Load more items from the source - /// - /// number of items to load - /// Async operation of LoadMoreItemsResult - /// Not implemented yet... - public IAsyncOperation LoadMoreItemsAsync(uint count) - { - var sil = _source as ISupportIncrementalLoading; - return sil?.LoadMoreItemsAsync(count); - } - - /// - /// Gets the groups in collection - /// - public IObservableVector CollectionGroups => null; - - /// - /// Gets or sets the current item - /// - public object CurrentItem - { - - get { return CurrentPosition > -1 && CurrentPosition < _view.Count ? _view[CurrentPosition] : null; } -#pragma warning restore CS8603 // Possible null reference return. - set { MoveCurrentTo(value); } - } - - /// - /// Gets the position of current item - /// - public int CurrentPosition { get; private set; } - - /// - /// Gets a value indicating whether the source has more items - /// - public bool HasMoreItems => (_source as ISupportIncrementalLoading)?.HasMoreItems ?? false; - - /// - /// Gets a value indicating whether the current item is after the last visible item - /// - public bool IsCurrentAfterLast => CurrentPosition >= _view.Count; - - /// - /// Gets a value indicating whether the current item is before the first visible item - /// - public bool IsCurrentBeforeFirst => CurrentPosition < 0; - - /// - /// Current item changed event handler - /// - public event EventHandler CurrentChanged; - - /// - /// Current item changing event handler - /// - public event CurrentChangingEventHandler CurrentChanging; - - /// - /// Gets a value indicating whether this CollectionView can filter its items - /// - public bool CanFilter => true; - - /// - /// Gets or sets the predicate used to filter the visible items - /// - public Predicate Filter - { - get - { - return _filter; - } - - set - { - if (_filter == value) - { - return; - } - - _filter = value; - HandleFilterChanged(); - } - } - - /// - /// Gets a value indicating whether this CollectionView can sort its items - /// - public bool CanSort => true; - - /// - /// Gets SortDescriptions to sort the visible items - /// - public IList SortDescriptions => _sortDescriptions; - - /* - /// - /// Gets a value indicating whether this CollectionView can group its items - /// - public bool CanGroup => false; - - /// - /// Gets GroupDescriptions to group the visible items - /// - public IList GroupDescriptions => null; - */ - - /// - /// Gets the source collection - /// - public IEnumerable SourceCollection => _source; - - /// - /// IComparer implementation - /// - /// Object A - /// Object B - /// Comparison value - int IComparer.Compare(object x, object y) - { - if (_sortProperties.Count == 0) - { - var listType = _source?.GetType(); - Type type; - - if (listType != null && listType.IsGenericType) - { - type = listType.GetGenericArguments()[0]; - } - else - { - type = x.GetType(); - } - - foreach (var sd in _sortDescriptions) - { - if (!string.IsNullOrEmpty(sd.PropertyName)) - { - _sortProperties[sd.PropertyName] = type.GetProperty(sd.PropertyName); - } - } - } - - foreach (var sd in _sortDescriptions) - { - object cx, cy; - - if (string.IsNullOrEmpty(sd.PropertyName)) - { - cx = x; - cy = y; - } - else - { - var pi = _sortProperties[sd.PropertyName]; - - cx = pi.GetValue(x!); - cy = pi.GetValue(y!); - } - - var cmp = sd.Comparer.Compare(cx, cy); - - if (cmp != 0) - { - return sd.Direction == SortDirection.Ascending ? +cmp : -cmp; - } - } - - return 0; - } - - /// - /// Occurs when a property value changes. - /// - public event PropertyChangedEventHandler? PropertyChanged; - - /// - /// Property changed event invoker - /// - /// name of the property that changed - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null!) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - /// - public void ObserveFilterProperty(string propertyName) - { - _observedFilterProperties.Add(propertyName); - } - - /// - public void ClearObservedFilterProperties() - { - _observedFilterProperties.Clear(); - } - - private void ItemOnPropertyChanged(object item, PropertyChangedEventArgs e) - { - if (!_liveShapingEnabled) - { - return; - } - - var filterResult = _filter?.Invoke(item); - - if (filterResult.HasValue && _observedFilterProperties.Contains(e.PropertyName)) - { - var viewIndex = _view.IndexOf(item); - if (viewIndex != -1 && !filterResult.Value) - { - RemoveFromView(viewIndex, item); - } - else if (viewIndex == -1 && filterResult.Value) - { - var index = _source.IndexOf(item); - HandleItemAdded(index, item); - } - } - - if ((filterResult ?? true) && SortDescriptions.Any(sd => sd.PropertyName == e.PropertyName)) - { - var oldIndex = _view.IndexOf(item); - - // Check if item is in view: - if (oldIndex < 0) - { - return; - } - - _view.RemoveAt(oldIndex); - var targetIndex = _view.BinarySearch(item, this); - if (targetIndex < 0) - { - targetIndex = ~targetIndex; - } - - // Only trigger expensive UI updates if the index really changed: - if (targetIndex != oldIndex) - { - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemRemoved, oldIndex, item)); - - _view.Insert(targetIndex, item); - - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.ItemInserted, targetIndex, item)); - } - else - { - _view.Insert(targetIndex, item); - } - } - else if (string.IsNullOrEmpty(e.PropertyName)) - { - HandleSourceChanged(); - } - } - - private void AttachPropertyChangedHandler(IEnumerable items) - { - if (!_liveShapingEnabled || items == null) - { - return; - } - - foreach (var item in items.OfType()) - { - item.PropertyChanged += ItemOnPropertyChanged; - } - } - - private void DetachPropertyChangedHandler(IEnumerable items) - { - if (!_liveShapingEnabled || items == null) - { - return; - } - - foreach (var item in items.OfType()) - { - item.PropertyChanged -= ItemOnPropertyChanged; - } - } - - private void HandleSortChanged() - { - _sortProperties.Clear(); - _view.Sort(this); - _sortProperties.Clear(); - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.Reset)); - } - - private void HandleFilterChanged() - { - if (_filter != null) - { - for (var index = 0; index < _view.Count; index++) - { - var item = _view.ElementAt(index); - if (_filter(item)) - { - continue; - } - - RemoveFromView(index, item); - index--; - } - } - - var viewHash = new HashSet(_view); - var viewIndex = 0; - for (var index = 0; index < _source.Count; index++) - { - var item = _source[index]; - if (viewHash.Contains(item)) - { - viewIndex++; - continue; - } - - if (HandleItemAdded(index, item, viewIndex)) - { - viewIndex++; - } - } - } - - private void HandleSourceChanged() - { - _sortProperties.Clear(); - var currentItem = CurrentItem; - _view.Clear(); - foreach (var item in Source) - { - if (_filter != null && !_filter(item)) - { - continue; - } - - if (_sortDescriptions.Any()) - { - var targetIndex = _view.BinarySearch(item, this); - if (targetIndex < 0) - { - targetIndex = ~targetIndex; - } - - _view.Insert(targetIndex, item); - } - else - { - _view.Add(item); - } - } - - _sortProperties.Clear(); - OnVectorChanged(new VectorChangedEventArgs(CollectionChange.Reset)); - MoveCurrentTo(currentItem); - } - - private void SourceNcc_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - // ReSharper disable once SwitchStatementMissingSomeCases - switch (e.Action) - { - case NotifyCollectionChangedAction.Add: - AttachPropertyChangedHandler(e.NewItems); - if (_deferCounter <= 0) - { - if (e.NewItems?.Count == 1) - { - HandleItemAdded(e.NewStartingIndex, e.NewItems[0]); - } - else - { - HandleSourceChanged(); - } - } - - break; - case NotifyCollectionChangedAction.Remove: - DetachPropertyChangedHandler(e.OldItems); - if (_deferCounter <= 0) - { - if (e.OldItems?.Count == 1) - { - HandleItemRemoved(e.OldStartingIndex, e.OldItems[0]); - } - else - { - HandleSourceChanged(); - } - } - - break; - case NotifyCollectionChangedAction.Move: - case NotifyCollectionChangedAction.Replace: - case NotifyCollectionChangedAction.Reset: - if (_deferCounter <= 0) - { - HandleSourceChanged(); - } - - break; - } - } - - private bool HandleItemAdded(int newStartingIndex, object newItem, int? viewIndex = null) - { - if (_filter != null && !_filter(newItem)) - { - return false; - } - - var newViewIndex = _view.Count; - - if (_sortDescriptions.Any()) - { - _sortProperties.Clear(); - newViewIndex = _view.BinarySearch(newItem, this); - if (newViewIndex < 0) - { - newViewIndex = ~newViewIndex; - } - } - else if (_filter != null) - { - if (_source == null) - { - HandleSourceChanged(); - return false; - } - - if (newStartingIndex == 0 || _view.Count == 0) - { - newViewIndex = 0; - } - else if (newStartingIndex == _source.Count - 1) - { - newViewIndex = _view.Count; - } - else if (viewIndex.HasValue) - { - newViewIndex = viewIndex.Value; - } - else - { - for (int i = 0, j = 0; i < _source.Count; i++) - { - if (i == newStartingIndex) - { - newViewIndex = j; - break; - } - - if (_view[j] == _source[i]) - { - j++; - } - } - } - } - - _view.Insert(newViewIndex, newItem); - if (newViewIndex <= CurrentPosition) - { - CurrentPosition++; - } - - var e = new VectorChangedEventArgs(CollectionChange.ItemInserted, newViewIndex, newItem); - OnVectorChanged(e); - return true; - } - - private void HandleItemRemoved(int oldStartingIndex, object oldItem) - { - if (_filter != null && !_filter(oldItem)) - { - return; - } - - if (oldStartingIndex < 0 || oldStartingIndex >= _view.Count || !Equals(_view[oldStartingIndex], oldItem)) - { - oldStartingIndex = _view.IndexOf(oldItem); - } - - if (oldStartingIndex < 0) - { - return; - } - - RemoveFromView(oldStartingIndex, oldItem); - } - - private void RemoveFromView(int itemIndex, object item) - { - if (itemIndex <= CurrentPosition) - { - CurrentPosition--; - } - - var e = new VectorChangedEventArgs(CollectionChange.ItemRemoved, itemIndex, item); - OnVectorChanged(e); - _view.RemoveAt(itemIndex); - } - - private void SortDescriptions_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (_deferCounter > 0) - { - return; - } - - HandleSortChanged(); - } - - private bool MoveCurrentToIndex(int i) - { - if (i < -1 || i >= _view.Count) - { - return false; - } - - if (i == CurrentPosition) - { - return false; - } - - var e = new CurrentChangingEventArgs(); - OnCurrentChanging(e); - if (e.Cancel) - { - return false; - } - - CurrentPosition = i; - OnCurrentChanged(null!); - return true; - } -} - -#pragma warning restore CS8769 -#pragma warning restore CS8622 -#pragma warning restore CS8601 -#pragma warning restore CS8600 -#pragma warning restore CS8604 -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. \ No newline at end of file diff --git a/src/Extensions/VectorChangedEventArgs.cs b/src/Extensions/VectorChangedEventArgs.cs deleted file mode 100644 index 51eb7b9..0000000 --- a/src/Extensions/VectorChangedEventArgs.cs +++ /dev/null @@ -1,38 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using Windows.Foundation.Collections; - -namespace Sungaila.SUBSTitute.Extensions; - -/// -/// Vector changed EventArgs -/// -/// -/// Initializes a new instance of the class. -/// -/// collection change type -/// index of item changed -/// item changed -#pragma warning disable CS9113 -internal partial class VectorChangedEventArgs(CollectionChange cc, int index = -1, object item = null!) : IVectorChangedEventArgs -#pragma warning restore CS9113 -{ - - /// - /// Gets the type of change that occurred in the vector. - /// - /// - /// The type of change in the vector. - /// - public CollectionChange CollectionChange { get; } = cc; - - /// - /// Gets the position where the change occurred in the vector. - /// - /// - /// The zero-based position where the change occurred in the vector, if applicable. - /// - public uint Index { get; } = (uint)index; -} diff --git a/src/Extensions/WindowExtensions.cs b/src/Extensions/WindowExtensions.cs deleted file mode 100644 index d040ddd..0000000 --- a/src/Extensions/WindowExtensions.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Microsoft.UI.Xaml; -using Sungaila.ImmersiveDarkMode.WinUI; -using System; -using Windows.UI.ViewManagement; - -namespace Sungaila.SUBSTitute.Extensions -{ - public static class WindowExtensions - { - public static void InitTitlebarTheme2(this Window window) - { - ArgumentNullException.ThrowIfNull(window); - - void colorValuesChangedHandler(UISettings sender, object args) => window.SetTitlebarTheme(); - - var uiSettings = new UISettings(); - uiSettings.ColorValuesChanged += colorValuesChangedHandler; - - void closedHandler(object sender, WindowEventArgs args) - { - window.Closed -= closedHandler; - uiSettings!.ColorValuesChanged -= colorValuesChangedHandler; - uiSettings = null; - }; - - window.Closed -= closedHandler; - window.Closed += closedHandler; - - window.SetTitlebarTheme(); - } - } -} diff --git a/src/SUBSTitute.csproj b/src/SUBSTitute.csproj index 364a941..b14a41b 100644 --- a/src/SUBSTitute.csproj +++ b/src/SUBSTitute.csproj @@ -94,12 +94,13 @@ + + - diff --git a/src/Strings/de-de/Resources.resw b/src/Strings/de-de/Resources.resw index 3e4cc61..37f9dde 100644 --- a/src/Strings/de-de/Resources.resw +++ b/src/Strings/de-de/Resources.resw @@ -141,10 +141,10 @@ Entfernen - + Laufwerk - + Dateisystem @@ -168,7 +168,7 @@ Unbekannt - + Typ @@ -201,7 +201,7 @@ Virtuelles Laufwerk - + Beschriftung diff --git a/src/Strings/en-us/Resources.resw b/src/Strings/en-us/Resources.resw index 66f30fc..c62182f 100644 --- a/src/Strings/en-us/Resources.resw +++ b/src/Strings/en-us/Resources.resw @@ -141,10 +141,10 @@ Remove - + Drive - + File system @@ -168,7 +168,7 @@ Unknown - + Type @@ -201,7 +201,7 @@ Virtual drive - + Label diff --git a/src/ViewModels/MappingViewModel.cs b/src/ViewModels/MappingViewModel.cs index dab7376..e81f1cf 100644 --- a/src/ViewModels/MappingViewModel.cs +++ b/src/ViewModels/MappingViewModel.cs @@ -1,7 +1,6 @@ using CommunityToolkit.Mvvm.Input; using CommunityToolkit.WinUI.Collections; using Sungaila.SUBSTitute.Commands; -using Sungaila.SUBSTitute.Extensions; using System.Collections.ObjectModel; using WinRT; @@ -21,7 +20,6 @@ public bool ShowAllDrives { App.LocalSettings.Values["MappingShowAllDrives"] = value; DrivesFiltered.RefreshFilter(); - DrivesFilteredForDataGrid.RefreshFilter(); } } } @@ -44,8 +42,6 @@ public int SelectedIndex public AdvancedCollectionView DrivesFiltered { get; } = []; - public HackedCollectionView DrivesFilteredForDataGrid { get; } = []; - public IRelayCommand QueryDrives { get; } = MappingCommands.QueryDrives; public IRelayCommand AddVirtualDrive { get; } = MappingCommands.AddVirtualDrive; @@ -55,10 +51,6 @@ public MappingViewModel() DrivesFiltered.Filter = FilterDrives; DrivesFiltered.Source = Drives; DrivesFiltered.SortDescriptions.Add(new SortDescription(nameof(DriveViewModel.Letter), SortDirection.Ascending)); - - DrivesFilteredForDataGrid.Filter = FilterDrives; - DrivesFilteredForDataGrid.Source = Drives; - DrivesFilteredForDataGrid.SortDescriptions.Add(new SortDescription(nameof(DriveViewModel.Path), SortDirection.Ascending)); } private bool FilterDrives(object obj) diff --git a/src/Views/GridView.xaml b/src/Views/GridView.xaml index 592764f..7e996bd 100644 --- a/src/Views/GridView.xaml +++ b/src/Views/GridView.xaml @@ -82,6 +82,6 @@ FlowDirection="LeftToRight" IsItemClickEnabled="False" ItemTemplate="{StaticResource LinedFlowLayoutItemTemplate}" - ItemsSource="{Binding DrivesFiltered}" + ItemsSource="{x:Bind Data.DrivesFiltered}" SelectionMode="None" /> \ No newline at end of file diff --git a/src/Views/GridView.xaml.cs b/src/Views/GridView.xaml.cs index e464f7b..9984da2 100644 --- a/src/Views/GridView.xaml.cs +++ b/src/Views/GridView.xaml.cs @@ -1,9 +1,12 @@ using Microsoft.UI.Xaml.Controls; +using Sungaila.SUBSTitute.ViewModels; namespace Sungaila.SUBSTitute.Views { public sealed partial class GridView : Page { + private MappingViewModel? Data => DataContext as MappingViewModel; + public GridView() { this.InitializeComponent(); diff --git a/src/Views/ListView.xaml b/src/Views/ListView.xaml index baaec4c..0256999 100644 --- a/src/Views/ListView.xaml +++ b/src/Views/ListView.xaml @@ -2,10 +2,12 @@ - - - - - - - - - - - - + - + + + + + - + + + + + + + + + - + + + + + + + + + + + + - - - - + + + + + - - - - - - - - - + + + + \ No newline at end of file diff --git a/src/Views/ListView.xaml.cs b/src/Views/ListView.xaml.cs index 506c36d..fd8e635 100644 --- a/src/Views/ListView.xaml.cs +++ b/src/Views/ListView.xaml.cs @@ -1,5 +1,3 @@ -using CommunityToolkit.WinUI.Collections; -using CommunityToolkit.WinUI.UI.Controls; using Microsoft.UI.Xaml.Controls; using Sungaila.SUBSTitute.ViewModels; @@ -7,49 +5,11 @@ namespace Sungaila.SUBSTitute.Views { public sealed partial class ListView : Page { + private MappingViewModel? Data => DataContext as MappingViewModel; + public ListView() { this.InitializeComponent(); } - - private void DataGrid_Sorting(object sender, DataGridColumnEventArgs e) - { - if (sender is not DataGrid dataGrid) - return; - - if (dataGrid.DataContext is not MappingViewModel mappingViewModel) - return; - - string? bindingPath; - - if (e.Column is DataGridBoundColumn boundColumn) - { - bindingPath = boundColumn.Binding.Path.Path; - } - else - { - bindingPath = e.Column.Tag as string; - } - - if (string.IsNullOrEmpty(bindingPath)) - return; - - mappingViewModel.DrivesFilteredForDataGrid.SortDescriptions.Clear(); - - foreach (var column in dataGrid.Columns) - { - if (column == e.Column) - continue; - - column.SortDirection = null; - } - - var newDirection = e.Column.SortDirection == DataGridSortDirection.Descending - ? DataGridSortDirection.Ascending - : DataGridSortDirection.Descending; - - mappingViewModel.DrivesFilteredForDataGrid.SortDescriptions.Add(new SortDescription(bindingPath, newDirection == DataGridSortDirection.Descending ? SortDirection.Descending : SortDirection.Ascending)); - e.Column.SortDirection = newDirection; - } } } \ No newline at end of file diff --git a/src/Views/MappingView.xaml b/src/Views/MappingView.xaml index 47626ec..71a7365 100644 --- a/src/Views/MappingView.xaml +++ b/src/Views/MappingView.xaml @@ -16,7 +16,7 @@ - + @@ -33,12 +33,12 @@ @@ -46,12 +46,12 @@ + IsChecked="{x:Bind Data.Mapping.ShowAllDrives, Mode=TwoWay}" /> - + \ No newline at end of file diff --git a/src/Views/MappingView.xaml.cs b/src/Views/MappingView.xaml.cs index 8b862dd..1203680 100644 --- a/src/Views/MappingView.xaml.cs +++ b/src/Views/MappingView.xaml.cs @@ -1,12 +1,15 @@ using CommunityToolkit.WinUI.Controls; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; +using Sungaila.SUBSTitute.ViewModels; using System; namespace Sungaila.SUBSTitute.Views { public sealed partial class MappingView : Page { + private MainViewModel? Data => DataContext as MainViewModel; + public MappingView() { this.InitializeComponent(); diff --git a/src/Views/RemoveDriveView.xaml b/src/Views/RemoveDriveView.xaml index 5a0ec54..bb6eb5a 100644 --- a/src/Views/RemoveDriveView.xaml +++ b/src/Views/RemoveDriveView.xaml @@ -25,7 +25,7 @@ Orientation="Horizontal" Spacing="5" Visibility="{x:Bind Data.IsPermanent, Mode=OneTime, Converter={StaticResource BoolToVisibilityConverter}}"> - +