11using System ;
22using System . Collections . Generic ;
3+ using System . Diagnostics . CodeAnalysis ;
34using System . Linq ;
45using WinUI . TableView . Extensions ;
56
@@ -25,36 +26,78 @@ public virtual IList<TableViewFilterItem> GetFilterItems(TableViewColumn column,
2526 {
2627 if ( column is { TableView . ItemsSource : { } } )
2728 {
28- var collectionView = new CollectionView ( column . TableView . ItemsSource ) ;
29+ var collectionView = new CollectionView ( liveShapingEnabled : false ) ;
2930 collectionView . FilterDescriptions . AddRange (
3031 column . TableView . FilterDescriptions . Where (
3132 x => x is not ColumnFilterDescription columnFilter || columnFilter . Column != column ) ) ;
33+ if ( searchText is { Length : > 0 } )
34+ {
35+ collectionView . FilterDescriptions . Add ( new FilterDescription ( default , item =>
36+ {
37+ var value = column . GetCellContent ( item ) ;
38+ return string . IsNullOrEmpty ( searchText ) ||
39+ value ? . ToString ( ) ? . Contains ( searchText , StringComparison . OrdinalIgnoreCase ) == true ;
40+ } ) ) ;
41+ }
42+
43+ collectionView . Source = column . TableView . ItemsSource ;
3244
33- return [ .. collectionView . Select ( column . GetCellContent )
34- . Select ( x => IsBlank ( x ) ? null : x )
35- . GroupBy ( x => x )
36- . OrderBy ( x => x . Key )
37- . Select ( x =>
38- {
39- var value = x . Key ;
40- value ??= TableViewLocalizedStrings . BlankFilterValue ;
41- var isSelected = ! column . IsFiltered || ! string . IsNullOrEmpty ( searchText ) ||
42- ( column . IsFiltered && SelectedValues [ column ] . Contains ( value ) ) ;
43-
44- return string . IsNullOrEmpty ( searchText )
45- || value ? . ToString ( ) ? . Contains ( searchText , StringComparison . OrdinalIgnoreCase ) == true
46- ? new TableViewFilterItem ( isSelected , value , x . Count ( ) )
47- : null ;
48-
49- } )
50- . OfType < TableViewFilterItem > ( )
51- . OrderByDescending ( x => _tableView . ShowFilterItemsCount ? x . Count : 0 ) ] ;
45+ var items = _tableView . ShowFilterItemsCount ?
46+ GetFilterItemsWithCount ( column , searchText , collectionView ) :
47+ GetFilterItems ( column , searchText , collectionView ) ;
48+
49+ return [ .. items ] ;
5250 }
5351
5452 return [ ] ;
5553 }
5654
57- private static bool IsBlank ( object ? value )
55+ private IEnumerable < TableViewFilterItem > GetFilterItemsWithCount ( TableViewColumn column , string ? searchText , CollectionView collectionView )
56+ {
57+ var nullCount = 0 ;
58+ var isNullItemSelected = ! column . IsFiltered || ! string . IsNullOrEmpty ( searchText ) ||
59+ ( column . IsFiltered && SelectedValues [ column ] . Contains ( null ) ) ;
60+ var filterValues = new SortedDictionary < object , int > ( ) ;
61+
62+ foreach ( var item in collectionView )
63+ {
64+ var value = column . GetCellContent ( item ) ;
65+
66+ if ( IsBlank ( value ) ) nullCount ++ ;
67+ else if ( filterValues . TryGetValue ( value , out var count ) ) filterValues [ value ] = ++ count ;
68+ else filterValues . Add ( value , 1 ) ;
69+ }
70+
71+ IEnumerable < TableViewFilterItem > nullFilterItem = nullCount > 0 ? [ new TableViewFilterItem ( isNullItemSelected , null , nullCount ) ] : [ ] ;
72+
73+ return [ .. nullFilterItem , .. filterValues . Select ( x =>
74+ {
75+ var isSelected = ! column . IsFiltered || ! string . IsNullOrEmpty ( searchText ) ||
76+ ( column . IsFiltered && SelectedValues [ column ] . Contains ( x . Key ) ) ;
77+ return new TableViewFilterItem ( isSelected , x . Key , x . Value ) ;
78+ } ) . OrderByDescending ( x=> x . Count ) ] ;
79+ }
80+
81+ private IEnumerable < TableViewFilterItem > GetFilterItems ( TableViewColumn column , string ? searchText , CollectionView collectionView )
82+ {
83+ var filterValues = new SortedSet < object ? > ( ) ;
84+
85+ foreach ( var item in collectionView )
86+ {
87+ var value = column . GetCellContent ( item ) ;
88+ value = IsBlank ( value ) ? null : value ;
89+ filterValues . Add ( value ) ;
90+ }
91+
92+ return [ .. filterValues . Select ( x =>
93+ {
94+ var isSelected = ! column . IsFiltered || ! string . IsNullOrEmpty ( searchText ) ||
95+ ( column . IsFiltered && SelectedValues [ column ] . Contains ( x ) ) ;
96+ return new TableViewFilterItem ( isSelected , x , 0 ) ;
97+ } ) ] ;
98+ }
99+
100+ private static bool IsBlank ( [ NotNullWhen ( false ) ] object ? value )
58101 {
59102 return value == null ||
60103 value == DBNull . Value ||
@@ -65,38 +108,33 @@ private static bool IsBlank(object? value)
65108 /// <inheritdoc/>
66109 public virtual void ApplyFilter ( TableViewColumn column )
67110 {
68- if ( column is { TableView : { } } )
111+ if ( column is { TableView . CollectionView : CollectionView { } collectionView } )
69112 {
113+ using var defer = collectionView . DeferRefresh ( ) ;
70114 column . TableView . DeselectAll ( ) ;
71115
72- if ( column . IsFiltered )
73- {
74- column . TableView . RefreshFilter ( ) ;
75- }
76- else
116+ if ( ! column . IsFiltered )
77117 {
78118 var boundColumn = column as TableViewBoundColumn ;
79119
80120 column . IsFiltered = true ;
81- column . TableView . FilterDescriptions . Add ( new ColumnFilterDescription (
121+ collectionView . FilterDescriptions . Add ( new ColumnFilterDescription (
82122 column ,
83123 boundColumn ? . PropertyPath ,
84124 ( o ) => Filter ( column , o ) ) ) ;
85125 }
86- column . TableView . RefreshFilter ( ) ;
87- column . TableView . EnsureAlternateRowColors ( ) ;
88126 }
89127 }
90128
91129 /// <inheritdoc/>
92130 public virtual void ClearFilter ( TableViewColumn ? column )
93131 {
94- if ( column is { TableView : { } } )
132+ if ( column is { TableView . CollectionView : CollectionView { } collectionView } )
95133 {
134+ using var defer = collectionView . DeferRefresh ( ) ;
96135 column . IsFiltered = false ;
97- column . TableView . FilterDescriptions . RemoveWhere ( x => x is ColumnFilterDescription columnFilter && columnFilter . Column == column ) ;
136+ collectionView . FilterDescriptions . RemoveWhere ( x => x is ColumnFilterDescription columnFilter && columnFilter . Column == column ) ;
98137 SelectedValues . RemoveWhere ( x => x . Key == column ) ;
99- column . TableView . RefreshFilter ( ) ;
100138 }
101139 else
102140 {
@@ -117,10 +155,10 @@ public virtual void ClearFilter(TableViewColumn? column)
117155 public virtual bool Filter ( TableViewColumn column , object ? item )
118156 {
119157 var value = column . GetCellContent ( item ) ;
120- value = IsBlank ( value ) ? TableViewLocalizedStrings . BlankFilterValue : value ! ;
158+ value = IsBlank ( value ) ? null : value ! ;
121159 return SelectedValues [ column ] . Contains ( value ) ;
122160 }
123161
124162 /// <inheritdoc/>
125- public IDictionary < TableViewColumn , IList < object > > SelectedValues { get ; } = new Dictionary < TableViewColumn , IList < object > > ( ) ;
163+ public IDictionary < TableViewColumn , ICollection < object ? > > SelectedValues { get ; } = new Dictionary < TableViewColumn , ICollection < object ? > > ( ) ;
126164}
0 commit comments