Disable Navigation Hotkeys in a WPF Navigation App
-
How can i disable navigation hotkeys in a wpf navigation app? For example the backspace key makes the app go back a page. I want to disable all such keyboard navigation. Thanks.
-jgoines
Answers
-
The navigation command bindings in quesiton are "class" bindings, not "instance". navWin.CommandBindings gives you the instance bindings. Class command bindings are added via CommandManager.RegisterClassCommandBinding(). However, since such bindings are an essential part of a control's implementation, they cannot be accessed directly or removed. Still, you can override class bindings like I showed you. This works because instance bindings take priority.
To add a handler for a routed command, do something like this:
navWin.CommandBindings.Add(
new CommandBinding(NavigationCommands.BrowseBack, OnBrowseBack));
void OnBrowseBack(object sender, ExecutedRoutedEventArgs args)
{
}I've been referring only to NavigationWindow so far, but Frame is very similar. The one special thing about it is that it handles the navigation commands only when it owns a journal. The JournalOwnership property controls this. The default depends on whether Frame is placed in a NavigationWindow or in an ordinary Window. If in a NW, it automatically starts using the NW's journal.
If your application doesn't need navigation functionality, consider these replacements:
NavigationWindow -> Window
Frame -> ContentControl
Then you can directly set the Content property programmatically, and you could still load pages via resource URIs by using Application.LoadComponent(Uri).But you mention you use PageFunctions, which definitely require navigation support. So, I am still not very certain to what extent your application needs the navigation support. If what you want is exactly to disable the UI ways of causing journal navigation, then adding empty handlers for the navigation commands and hiding NW's/Frame's navigation chrome should be enough for you. Then you can still navigate programmatically, and PageFunctions will still work, except the user will not be able to go back & forward between multiple pages of a navigation-based "wizard" (provided one PF invokes another..).
All Replies
-
I'm still looking for the answer to this. I can't seem to find a component anywhere that is processing these navigation hot keys. It doesn't seem to be the Page objects that are doing it. And the NavigationService doesn't seem to have any handlers for keyboard events. Can anyone help me disable keyboard navigation throughout my entire application?
-Ryan
-
Hi Ryan,
It's interesting to hear why you want to disable the navigation keys. The fact that they work doesn't sound like a problem in itself. ;-)
But to answer your questions specifically: It's NavigationWindow that handles the keys. It has class command bindings for most of the NavigationCommands (for example, NavigationCommands.BrowseBack, .BrowseStop). There is no way to remove a class command binding, but in any case I don't think that's what your goal is, since if you could do that, NavigationWindow would hardly work as such anymore, so why not just use an ordinary Window?
Here's one way to "trap" specific keys and prevent them from triggering the associated commands:
navWin.InputBindings.Add(new InputBinding(ApplicationCommands.NotACommand, new KeyGesture(Key.Back)));
navWin.InputBindings.Add(new InputBinding(ApplicationCommands.NotACommand, new KeyGesture(Key.Left, ModifierKeys.Alt)));But keep in mind there are other ways to navigate back: mouse XBUTTON (or any other configurable button), the BrowseBack key on multimedia keyboards. If you want to disable them as well, you could add an empty handler for ApplicationCommands.BrowseBack, but that's already pretty crippling, so I'm wondering again what your goal is.
-
I have an application that is made up of a window and some frames. The application changes itself by changing the Page displayed in the frame. So different 'screens' are different Page objects displayed in various frames. The nature of my app is that the Back and Forward Web Page navigation doesn't make sense. There is no concept of Back and Forward in my app. My application will handle the navigation itself, I don't want this Back and Forward metaphor imposed on me by WPF Navigation. This seems very intrusive. Is there another way I should be building an app like this? This seems like a good way to do it and it would be working great were there some way to get navigation to stop responding to keyboard input. The problem with disabling all browse back functionality is that PageFunctions, which I use in my app, use Back Navigation to function. I don't want to disable any navigation features, i just want to disable the hotkeys that trigger them.
-Ryan
-
I looked at my NavigationWindow object and its CommandBinding collection is empty. I still can't find the source of these hotkey commands.
-
The NavigationWindow does not seem to be the source of the keyboard navigation. I assign it a keydown event handler but this event does not fire even though pressing Backspace still results in the app navigating back.
-Ryan
-
How can I 'add an empty handler for Application.BrowseBack'? I want to disable all ways a user can navigation without using my interface.
-Ryan
-
Handle the Navigated Event on your NavigationWindow and in the handler call RemoveBackEntry(). This will make sure that there is nothing available to navigate back to.
-
The navigation command bindings in quesiton are "class" bindings, not "instance". navWin.CommandBindings gives you the instance bindings. Class command bindings are added via CommandManager.RegisterClassCommandBinding(). However, since such bindings are an essential part of a control's implementation, they cannot be accessed directly or removed. Still, you can override class bindings like I showed you. This works because instance bindings take priority.
To add a handler for a routed command, do something like this:
navWin.CommandBindings.Add(
new CommandBinding(NavigationCommands.BrowseBack, OnBrowseBack));
void OnBrowseBack(object sender, ExecutedRoutedEventArgs args)
{
}I've been referring only to NavigationWindow so far, but Frame is very similar. The one special thing about it is that it handles the navigation commands only when it owns a journal. The JournalOwnership property controls this. The default depends on whether Frame is placed in a NavigationWindow or in an ordinary Window. If in a NW, it automatically starts using the NW's journal.
If your application doesn't need navigation functionality, consider these replacements:
NavigationWindow -> Window
Frame -> ContentControl
Then you can directly set the Content property programmatically, and you could still load pages via resource URIs by using Application.LoadComponent(Uri).But you mention you use PageFunctions, which definitely require navigation support. So, I am still not very certain to what extent your application needs the navigation support. If what you want is exactly to disable the UI ways of causing journal navigation, then adding empty handlers for the navigation commands and hiding NW's/Frame's navigation chrome should be enough for you. Then you can still navigate programmatically, and PageFunctions will still work, except the user will not be able to go back & forward between multiple pages of a navigation-based "wizard" (provided one PF invokes another..).
-
Thanks so much, overriding the command bindings works perfectly and solves my problem. The question of whether or not I should be using a Navigation app is an interesting one. I could probably mimic all my functionality using a normal Window, and programmatically setting the content of the window. However I do make use of PageFunctions and they are very convenient at times and I'd have to do some extra work to mimic that functionality.
-Ryan
-
Good thread. I am writing a UI that is similar to Ryan's, and I like the built in functionality of Page Functions as well as the "framed" approach to loading pages. This somewhat mimics a MasterPage in ASP.NET, and is great for maintainability.
The way we are using the navigation framework may or may not be as Microsoft intended, but I am happy with the readability and conciseness of my code thus far.
Doug