diff --git a/src/ColumnFilterHandler.cs b/src/ColumnFilterHandler.cs
index a6cfa0a..adbeb7e 100644
--- a/src/ColumnFilterHandler.cs
+++ b/src/ColumnFilterHandler.cs
@@ -1,109 +1,810 @@
using System;
+using System.Collections;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.UI.Input;
+using Microsoft.UI.Xaml.Controls;
+using Windows.System;
using WinUI.TableView.Extensions;
namespace WinUI.TableView;
///
-/// Default implementation of the IColumnFilterHandler interface.
+/// Fast filter and sorting implementation with unified single code path for Options Flyout and header clicks.
///
public class ColumnFilterHandler : IColumnFilterHandler
{
private readonly TableView _tableView;
- ///
- /// Initializes a new instance of the ColumnFilterHandler class.
- ///
+ // SMART CACHE: Uses intelligent cache keys that include filter state
+ private readonly ConcurrentDictionary> _smartUniqueValuesCache = new();
+ private readonly ConcurrentDictionary> _activeFilters = new();
+ private readonly ConcurrentDictionary> _propertyAccessors = new();
+
+ // UNIFIED SORTING ENGINE - SINGLE CODE PATH
+ private TableViewColumn? _currentSortColumn;
+ private SortDirection? _currentSortDirection;
+ private readonly FastSortingEngine _sortingEngine;
+
+ private readonly FastFilterEngine _filterEngine;
+ private object? _lastItemsSource;
+ private IList? _originalItemsSource;
+ private IList? _currentFilteredSource;
+
+ // CRITICAL: Prevent infinite loops between filtering and sorting
+ private volatile bool _isApplyingFilterOrSort;
+
+ // SCROLL POSITION PRESERVATION: Store scroll position for restoration
+ private double _preservedHorizontalOffset = 0;
+ private ScrollViewer? _cachedScrollViewer = null;
+
public ColumnFilterHandler(TableView tableView)
{
_tableView = tableView;
+ _filterEngine = new FastFilterEngine();
+ _sortingEngine = new FastSortingEngine();
+ SelectedValues = new SelectedValuesWrapper(this);
+
+ // Hook into ALL sorting events to unify the code path
+ HookIntoAllSortingEvents();
}
- ///
- public virtual IList GetFilterItems(TableViewColumn column, string? searchText = default)
+ ///
+ /// UNIFIED: Hook into all sorting events to create a single fast code path
+ ///
+ private void HookIntoAllSortingEvents()
{
- if (column is { TableView.ItemsSource: { } })
+ // Hook into TableView sorting event (header clicks)
+ _tableView.Sorting += OnTableViewSorting;
+
+ // Hook into ClearSorting event
+ _tableView.ClearSorting += OnTableViewClearSorting;
+ }
+
+ ///
+ /// UNIFIED: Single entry point for all sorting operations
+ ///
+ private void OnTableViewSorting(object? sender, TableViewSortingEventArgs e)
+ {
+ // CRITICAL: Prevent infinite loops
+ if (_isApplyingFilterOrSort)
+ {
+ return;
+ }
+
+ // Mark event as handled so TableView doesn't process it
+ e.Handled = true;
+
+ // CRITICAL: Ensure we have original data before any sorting operation
+ EnsureOriginalDataSource();
+
+ // Handle the sorting with our unified fast engine
+ HandleUnifiedSort(e.Column);
+ }
+
+ ///
+ /// UNIFIED: Single entry point for clearing sorts
+ ///
+ private void OnTableViewClearSorting(object? sender, TableViewClearSortingEventArgs e)
+ {
+ // CRITICAL: Prevent infinite loops
+ if (_isApplyingFilterOrSort)
{
- var collectionView = new CollectionView(column.TableView.ItemsSource);
- collectionView.FilterDescriptions.AddRange(
- column.TableView.FilterDescriptions.Where(
- x => x is not ColumnFilterDescription columnFilter || columnFilter.Column != column));
+ return;
+ }
+
+ // Mark event as handled so TableView doesn't process it
+ e.Handled = true;
- var filterValues = new SortedSet