none
Disable Navigation Hotkeys in a WPF Navigation App

    Question

  • 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

    Tuesday, September 26, 2006 6:49 PM

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..).

     

    Friday, September 29, 2006 10:45 PM

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

    Friday, September 29, 2006 7:03 PM
  • 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.

     

    Friday, September 29, 2006 7:51 PM
  • 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

    Friday, September 29, 2006 8:28 PM
  • I looked at my NavigationWindow object and its CommandBinding collection is empty.  I still can't find the source of these hotkey commands.
    Friday, September 29, 2006 8:37 PM
  • 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

    Friday, September 29, 2006 8:41 PM
  • 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

    Friday, September 29, 2006 9:29 PM
  • 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.
    Friday, September 29, 2006 10:06 PM
    Moderator
  • 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..).

     

    Friday, September 29, 2006 10:45 PM
  • 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

    Saturday, September 30, 2006 1:37 AM
  • 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
    Wednesday, April 04, 2007 6:49 PM
  • Frame f;
    f.CommandBindings.Clear()

    Monday, March 30, 2009 8:29 AM
  • You could always remove the command binding completely. thr frame.CommandBindings.Clear() doesn't seem to do the job.

     

     

    If Frame.CommandBindings.Count <> 0 Then

     

    Dim i = 0

     

    While i <> Frame.CommandBindings.Count

    Frame.CommandBindings.Remove(Frame.CommandBindings.Item(i))

     

    End While

     

    End If

    This does the trick without losing the ability to navigate through code.

    Monday, September 28, 2009 1:49 PM
  • This isn't the best way, but if you dont want to change all your pages do User controls an use ContentControl, you can do this:

    public static void RemoveHotKeysFromFrmContent(Frame frmContent)
            {
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseHome, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.DecreaseZoom, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.Favorites, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.FirstPage, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.GoToPage, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.IncreaseZoom, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.LastPage, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.NavigateJournal, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.NextPage, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.PreviousPage, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.Search, EmptyEvent));
                frmContent.CommandBindings.Add(new CommandBinding(NavigationCommands.Zoom, EmptyEvent));
            }
    
            static void EmptyEvent(object sender, ExecutedRoutedEventArgs args)
            {
                Debug.WriteLine(@"Hotkey Navigation Intercepted");
            }
    

     And just call this static method passing the Frame control.

    Hope it helps.

     


    Leandro Medeiros, MCP .Net Framework
    Thursday, October 20, 2011 7:56 PM
  • i needed to disable the Backspace binding for my app.  This code at app startup does so:

    			foreach (InputGesture gesture in NavigationCommands.BrowseBack.InputGestures)
    			{
    				if (gesture is KeyGesture && ((KeyGesture)gesture).DisplayString.Equals("Backspace"))
    				{
    					NavigationCommands.BrowseBack.InputGestures.Remove(gesture);
    					break;
    				}
    			}

    Thursday, May 16, 2013 7:07 PM