1515using System . IO ;
1616using System . Runtime . CompilerServices ;
1717using System . Runtime . InteropServices . ComTypes ;
18+ using System . Text ;
1819using Vanara . Extensions ;
1920using Vanara . PInvoke ;
2021using Windows . ApplicationModel . DataTransfer ;
2324using Windows . Foundation . Collections ;
2425using Windows . Storage ;
2526using Windows . System ;
27+ using Windows . Win32 ;
2628using static Files . App . Helpers . PathNormalization ;
2729using DispatcherQueueTimer = Microsoft . UI . Dispatching . DispatcherQueueTimer ;
2830using SortDirection = Files . App . Data . Enums . SortDirection ;
@@ -40,6 +42,8 @@ public abstract class BaseLayoutPage : Page, IBaseLayoutPage, INotifyPropertyCha
4042 protected IFileTagsSettingsService FileTagsSettingsService { get ; } = Ioc . Default . GetService < IFileTagsSettingsService > ( ) ! ;
4143 protected IUserSettingsService UserSettingsService { get ; } = Ioc . Default . GetService < IUserSettingsService > ( ) ! ;
4244 protected ILayoutSettingsService LayoutSettingsService { get ; } = Ioc . Default . GetService < ILayoutSettingsService > ( ) ! ;
45+ protected IGeneralSettingsService GeneralSettingsService { get ; } = Ioc . Default . GetService < IGeneralSettingsService > ( ) ! ;
46+ protected IFoldersSettingsService FoldersSettingsService { get ; } = Ioc . Default . GetService < IFoldersSettingsService > ( ) ! ;
4347 protected ICommandManager Commands { get ; } = Ioc . Default . GetRequiredService < ICommandManager > ( ) ;
4448 public InfoPaneViewModel InfoPaneViewModel { get ; } = Ioc . Default . GetRequiredService < InfoPaneViewModel > ( ) ;
4549 protected readonly IWindowContext WindowContext = Ioc . Default . GetRequiredService < IWindowContext > ( ) ;
@@ -401,7 +405,7 @@ protected override async void OnNavigatedTo(NavigationEventArgs e)
401405 base . OnNavigatedTo ( e ) ;
402406
403407 // Add item jumping handler
404- CharacterReceived += Page_CharacterReceived ;
408+ PreviewKeyDown += Page_PreviewKeyDown ; ;
405409
406410 navigationArguments = ( NavigationArguments ) e . Parameter ;
407411 ParentShellPageInstance = navigationArguments . AssociatedTabInstance ;
@@ -565,7 +569,7 @@ protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
565569 base . OnNavigatingFrom ( e ) ;
566570
567571 // Remove item jumping handler
568- CharacterReceived -= Page_CharacterReceived ;
572+ PreviewKeyDown -= Page_PreviewKeyDown ;
569573 FolderSettings ! . LayoutModeChangeRequested -= BaseFolderSettings_LayoutModeChangeRequested ;
570574 FolderSettings . GroupOptionPreferenceUpdated -= FolderSettings_GroupOptionPreferenceUpdated ;
571575 FolderSettings . GroupDirectionPreferenceUpdated -= FolderSettings_GroupDirectionPreferenceUpdated ;
@@ -996,12 +1000,83 @@ private void RemoveOverflow(CommandBarFlyout contextMenuFlyout)
9961000 overflowSeparator . Visibility = Visibility . Collapsed ;
9971001 }
9981002
999- protected virtual void Page_CharacterReceived ( UIElement sender , CharacterReceivedRoutedEventArgs args )
1003+ protected virtual void Page_PreviewKeyDown ( object sender , KeyRoutedEventArgs e )
10001004 {
1001- if ( ParentShellPageInstance ! . IsCurrentInstance )
1005+ var shellPage = ParentShellPageInstance ;
1006+ if ( shellPage ? . IsCurrentInstance != true )
1007+ return ;
1008+
1009+ var pressedKey = e . Key ;
1010+ var currentFilter = shellPage . ShellViewModel . FilesAndFoldersFilter ?? string . Empty ;
1011+ var isFilterModeOn = FoldersSettingsService . KeyboardTypingBehavior == KeyboardTypingBehavior . FilterItems ;
1012+ var buffer = new StringBuilder ( 4 ) ;
1013+ var state = new byte [ 256 ] ;
1014+ char ? typedCharacter = null ;
1015+
1016+ if ( PInvoke . GetKeyboardState ( state ) )
1017+ {
1018+ var virtualKey = ( uint ) pressedKey ;
1019+ var scanCode = PInvoke . MapVirtualKey ( virtualKey , 0 ) ;
1020+ var keyboardLayout = PInvoke . GetKeyboardLayout ( 0 ) ;
1021+
1022+ if ( Win32PInvoke . ToUnicodeEx ( virtualKey , scanCode , state , buffer , buffer . Capacity , 0 , keyboardLayout ) > 0 )
1023+ {
1024+ var character = buffer [ ^ 1 ] ;
1025+ if ( character != ' ' )
1026+ typedCharacter = character ;
1027+ }
1028+ }
1029+
1030+ // Handle valid character input
1031+ if ( typedCharacter . HasValue && ! Path . GetInvalidFileNameChars ( ) . Contains ( char . ToLowerInvariant ( typedCharacter . Value ) ) )
1032+ {
1033+ var lowerCharString = char . ToLowerInvariant ( typedCharacter . Value ) . ToString ( ) ;
1034+
1035+ if ( isFilterModeOn )
1036+ {
1037+ if ( ! GeneralSettingsService . ShowFilterHeader )
1038+ GeneralSettingsService . ShowFilterHeader = true ;
1039+ shellPage . ShellViewModel . FilesAndFoldersFilter += lowerCharString ;
1040+ }
1041+ else
1042+ {
1043+ JumpString += lowerCharString ;
1044+ }
1045+ }
1046+ // Handle special keys in filter mode
1047+ else if ( isFilterModeOn && ! string . IsNullOrEmpty ( currentFilter ) )
10021048 {
1003- char letter = args . Character ;
1004- JumpString += letter . ToString ( ) . ToLowerInvariant ( ) ;
1049+ switch ( pressedKey )
1050+ {
1051+ case VirtualKey . Space :
1052+ shellPage . ShellViewModel . FilesAndFoldersFilter += " " ;
1053+ break ;
1054+
1055+ case VirtualKey . Back when currentFilter . Length > 1 :
1056+ shellPage . ShellViewModel . FilesAndFoldersFilter = currentFilter [ ..^ 1 ] ;
1057+ break ;
1058+
1059+ case VirtualKey . Back when currentFilter . Length == 1 :
1060+ shellPage . ShellViewModel . FilesAndFoldersFilter = string . Empty ;
1061+ GeneralSettingsService . ShowFilterHeader = false ;
1062+ break ;
1063+ }
1064+ }
1065+
1066+ // Update selection in filter mode
1067+ if ( isFilterModeOn )
1068+ {
1069+ var filterText = shellPage . ShellViewModel . FilesAndFoldersFilter ;
1070+ var matchedItem = shellPage . ShellViewModel . FilesAndFolders
1071+ . FirstOrDefault ( item => ! string . IsNullOrEmpty ( filterText ) &&
1072+ item . Name ? . Contains ( filterText , StringComparison . OrdinalIgnoreCase ) == true ) ;
1073+
1074+ if ( matchedItem != null )
1075+ {
1076+ ItemManipulationModel . SetSelectedItem ( matchedItem ) ;
1077+ ItemManipulationModel . ScrollIntoView ( matchedItem ) ;
1078+ ItemManipulationModel . FocusSelectedItems ( ) ;
1079+ }
10051080 }
10061081 }
10071082
0 commit comments