1
1
using ByteSizeLib ;
2
- using Files . Interacts ;
2
+ using Files . Enums ;
3
3
using Files . Navigation ;
4
4
using Microsoft . Toolkit . Uwp . UI ;
5
5
using Microsoft . UI . Xaml . Controls ;
6
6
using System ;
7
7
using System . Collections . Generic ;
8
8
using System . Collections . ObjectModel ;
9
+ using System . ComponentModel ;
9
10
using System . Diagnostics ;
10
11
using System . Globalization ;
11
12
using System . IO ;
12
13
using System . Linq ;
14
+ using System . Runtime . CompilerServices ;
13
15
using System . Runtime . InteropServices ;
14
16
using System . Threading ;
15
17
using System . Threading . Tasks ;
31
33
32
34
namespace Files . Filesystem
33
35
{
34
- public class ItemViewModel
36
+ public class ItemViewModel : INotifyPropertyChanged
35
37
{
36
38
public ReadOnlyObservableCollection < ListedItem > FilesAndFolders { get ; }
37
39
public CollectionViewSource viewSource ;
@@ -44,10 +46,133 @@ public class ItemViewModel
44
46
private QueryOptions _options ;
45
47
private volatile bool _filesRefreshing ;
46
48
private const int _step = 250 ;
49
+ public event PropertyChangedEventHandler PropertyChanged ;
50
+
51
+ private SortOption _directorySortOption = SortOption . Name ;
52
+ private SortDirection _directorySortDirection = SortDirection . Ascending ;
53
+
54
+ public SortOption DirectorySortOption
55
+ {
56
+ get
57
+ {
58
+ return _directorySortOption ;
59
+ }
60
+ set
61
+ {
62
+ if ( value != _directorySortOption )
63
+ {
64
+ _directorySortOption = value ;
65
+ NotifyPropertyChanged ( "DirectorySortOption" ) ;
66
+ NotifyPropertyChanged ( "IsSortedByName" ) ;
67
+ NotifyPropertyChanged ( "IsSortedByDate" ) ;
68
+ NotifyPropertyChanged ( "IsSortedByType" ) ;
69
+ NotifyPropertyChanged ( "IsSortedBySize" ) ;
70
+ OrderFiles ( ) ;
71
+ }
72
+ }
73
+ }
74
+
75
+ public SortDirection DirectorySortDirection
76
+ {
77
+ get
78
+ {
79
+ return _directorySortDirection ;
80
+ }
81
+ set
82
+ {
83
+ if ( value != _directorySortDirection )
84
+ {
85
+ _directorySortDirection = value ;
86
+ NotifyPropertyChanged ( "DirectorySortDirection" ) ;
87
+ NotifyPropertyChanged ( "IsSortedAscending" ) ;
88
+ NotifyPropertyChanged ( "IsSortedDescending" ) ;
89
+ OrderFiles ( ) ;
90
+ }
91
+ }
92
+ }
93
+
94
+ public bool IsSortedByName
95
+ {
96
+ get => DirectorySortOption == SortOption . Name ;
97
+ set
98
+ {
99
+ if ( value )
100
+ {
101
+ DirectorySortOption = SortOption . Name ;
102
+ NotifyPropertyChanged ( "IsSortedByName" ) ;
103
+ NotifyPropertyChanged ( "DirectorySortOption" ) ;
104
+ }
105
+ }
106
+ }
107
+
108
+ public bool IsSortedByDate
109
+ {
110
+ get => DirectorySortOption == SortOption . DateModified ;
111
+ set
112
+ {
113
+ if ( value )
114
+ {
115
+ DirectorySortOption = SortOption . DateModified ;
116
+ NotifyPropertyChanged ( "IsSortedByDate" ) ;
117
+ NotifyPropertyChanged ( "DirectorySortOption" ) ;
118
+ }
119
+ }
120
+ }
121
+
122
+ public bool IsSortedByType
123
+ {
124
+ get => DirectorySortOption == SortOption . FileType ;
125
+ set
126
+ {
127
+ if ( value )
128
+ {
129
+ DirectorySortOption = SortOption . FileType ;
130
+ NotifyPropertyChanged ( "IsSortedByType" ) ;
131
+ NotifyPropertyChanged ( "DirectorySortOption" ) ;
132
+ }
133
+ }
134
+ }
135
+
136
+ public bool IsSortedBySize
137
+ {
138
+ get => DirectorySortOption == SortOption . Size ;
139
+ set
140
+ {
141
+ if ( value )
142
+ {
143
+ DirectorySortOption = SortOption . Size ;
144
+ NotifyPropertyChanged ( "IsSortedBySize" ) ;
145
+ NotifyPropertyChanged ( "DirectorySortOption" ) ;
146
+ }
147
+ }
148
+ }
149
+
150
+ public bool IsSortedAscending
151
+ {
152
+ get => DirectorySortDirection == SortDirection . Ascending ;
153
+ set
154
+ {
155
+ DirectorySortDirection = value ? SortDirection . Ascending : SortDirection . Descending ;
156
+ NotifyPropertyChanged ( "IsSortedAscending" ) ;
157
+ NotifyPropertyChanged ( "IsSortedDescending" ) ;
158
+ NotifyPropertyChanged ( "DirectorySortDirection" ) ;
159
+ }
160
+ }
161
+
162
+ public bool IsSortedDescending
163
+ {
164
+ get => ! IsSortedAscending ;
165
+ set
166
+ {
167
+ DirectorySortDirection = value ? SortDirection . Descending : SortDirection . Ascending ;
168
+ NotifyPropertyChanged ( "IsSortedAscending" ) ;
169
+ NotifyPropertyChanged ( "IsSortedDescending" ) ;
170
+ NotifyPropertyChanged ( "DirectorySortDirection" ) ;
171
+ }
172
+ }
47
173
48
174
public ItemViewModel ( )
49
175
{
50
-
51
176
_filesAndFolders = new ObservableCollection < ListedItem > ( ) ;
52
177
53
178
FilesAndFolders = new ReadOnlyObservableCollection < ListedItem > ( _filesAndFolders ) ;
@@ -250,6 +375,59 @@ public void CancelLoadAndClearFiles()
250
375
251
376
}
252
377
378
+ public void OrderFiles ( )
379
+ {
380
+ if ( _filesAndFolders . Count == 0 )
381
+ return ;
382
+
383
+ object orderByNameFunc ( ListedItem item ) => item . FileName ;
384
+ Func < ListedItem , object > orderFunc = orderByNameFunc ;
385
+ switch ( DirectorySortOption )
386
+ {
387
+ case SortOption . Name :
388
+ orderFunc = orderByNameFunc ;
389
+ break ;
390
+ case SortOption . DateModified :
391
+ orderFunc = item => item . FileDateReal ;
392
+ break ;
393
+ case SortOption . FileType :
394
+ orderFunc = item => item . FileType ;
395
+ break ;
396
+ case SortOption . Size :
397
+ orderFunc = item => item . FileSizeBytes ;
398
+ break ;
399
+ }
400
+
401
+ // In ascending order, show folders first, then files.
402
+ // So, we use != "Folder" to make the value for "Folder" = 0, and for the rest, 1.
403
+ Func < ListedItem , bool > folderThenFile = listedItem => listedItem . FileType != "Folder" ;
404
+ IOrderedEnumerable < ListedItem > ordered ;
405
+ List < ListedItem > orderedList ;
406
+
407
+ if ( DirectorySortDirection == SortDirection . Ascending )
408
+ ordered = _filesAndFolders . OrderBy ( folderThenFile ) . ThenBy ( orderFunc ) ;
409
+ else
410
+ {
411
+ if ( DirectorySortOption == SortOption . FileType )
412
+ ordered = _filesAndFolders . OrderBy ( folderThenFile ) . ThenByDescending ( orderFunc ) ;
413
+ else
414
+ ordered = _filesAndFolders . OrderByDescending ( folderThenFile ) . ThenByDescending ( orderFunc ) ;
415
+ }
416
+
417
+ // Further order by name if applicable
418
+ if ( DirectorySortOption != SortOption . Name )
419
+ {
420
+ if ( DirectorySortDirection == SortDirection . Ascending )
421
+ ordered = ordered . ThenBy ( orderByNameFunc ) ;
422
+ else
423
+ ordered = ordered . ThenByDescending ( orderByNameFunc ) ;
424
+ }
425
+ orderedList = ordered . ToList ( ) ;
426
+ _filesAndFolders . Clear ( ) ;
427
+ foreach ( ListedItem i in orderedList )
428
+ _filesAndFolders . Add ( i ) ;
429
+ }
430
+
253
431
public static T GetCurrentSelectedTabInstance < T > ( )
254
432
{
255
433
Frame rootFrame = Window . Current . Content as Frame ;
@@ -435,6 +613,7 @@ public async void AddItemsToCollectionAsync(string path)
435
613
( App . selectedTabInstance . accessibleContentFrame . Content as PhotoAlbum ) . TextState . isVisible = Visibility . Visible ;
436
614
}
437
615
}
616
+ OrderFiles ( ) ;
438
617
stopwatch . Stop ( ) ;
439
618
Debug . WriteLine ( "Loading of items in " + Universal . path + " completed in " + stopwatch . ElapsedMilliseconds + " milliseconds.\n " ) ;
440
619
App . selectedTabInstance . RefreshButton . IsEnabled = true ;
@@ -517,7 +696,7 @@ private async Task AddFolder(StorageFolder folder)
517
696
FilePath = folder . Path ,
518
697
EmptyImgVis = Visibility . Collapsed ,
519
698
FileSize = null ,
520
- RowIndex = _filesAndFolders . Count
699
+ FileSizeBytes = 0
521
700
} ) ;
522
701
if ( ( App . selectedTabInstance . accessibleContentFrame . Content as GenericFileBrowser ) != null )
523
702
{
@@ -538,6 +717,7 @@ private async Task AddFile(StorageFile file)
538
717
var itemDate = basicProperties . DateModified ;
539
718
var itemPath = file . Path ;
540
719
var itemSize = ByteSize . FromBytes ( basicProperties . Size ) . ToString ( ) ;
720
+ var itemSizeBytes = basicProperties . Size ;
541
721
var itemType = file . DisplayType ;
542
722
var itemFolderImgVis = Visibility . Collapsed ;
543
723
var itemFileExtension = file . FileType ;
@@ -616,7 +796,7 @@ private async Task AddFile(StorageFile file)
616
796
FileType = itemType ,
617
797
FilePath = itemPath ,
618
798
FileSize = itemSize ,
619
- RowIndex = _filesAndFolders . Count
799
+ FileSizeBytes = itemSizeBytes
620
800
} ) ;
621
801
622
802
if ( App . selectedTabInstance . accessibleContentFrame . SourcePageType == typeof ( GenericFileBrowser ) )
@@ -724,5 +904,9 @@ await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPrio
724
904
_filesRefreshing = false ;
725
905
Debug . WriteLine ( "Filesystem refresh complete" ) ;
726
906
}
907
+ private void NotifyPropertyChanged ( [ CallerMemberName ] string propertyName = "" )
908
+ {
909
+ PropertyChanged ? . Invoke ( this , new PropertyChangedEventArgs ( propertyName ) ) ;
910
+ }
727
911
}
728
912
}
0 commit comments