Is there a way I enable users to switch tabs in a tab control using control-pageup/pagedown (as in Chrome), so I can free up control-tab for use in the body of the tab? Do I have to write a previewKeyDown or something, switch tabs programmatically and set event.Handled = true? In that case, how do I stop xamTabControl from interfering with the ctrl-tab keypress?
Thanks.
John.
Hello John,
Thank you for your post.
I have been looking into your requirements. What I can suggest is to handle the PreviewKeyDown event of XamTabControl and set the IsTabStop wpf property. To stop the Ctrl + Tab combination you can use Keyboard.Modifiers method in 'if' statement in the event handler and set e.handled to true. Also you can move the tabs with PageUp and PageDown buttons by checking in the event handler for it and change the selected item by changing the selected index. You can change it by using SelectedIndex property of XamTabControl. I created a short sample application to show you how you can achieve the functionality that you want. Please let me know if I missing something.
Please let me know if you need from any further assistance on this matter.
Thanks, Zhivko, but it doesn't help. As I said in my original post, I need to be able to use ctrl-TAB in my own program.
I'm attaching a modified version of what you sent me. As you can see, the TextBox inside the tab has AcceptsTab="True". Once I fall into that TextBox, I want to be able to use ctrl-Tab to get out of it. Setting e.Handled=True in the preview key handler prevents ctrl-tab from being seen by the TextBox.
I don't think you'll be able to get this to work using just the wpf framework implementation if you expect it to cycle into the controls of each tab between going to each tab. I think the reason why it never gets to the 3rd tab is because of how they have it implemented. Basically they start with the focused element and then traverse the tree based on its tab index. The tabs all have the same tabindex so its more of a resolved tab index based on their zindex. Since the selected tab is the highest zindex it ends up going back to the 1st tab when the 2nd tab is selected and you press ctrl-tab. You can address that by setting the TabIndex of the TabItems. That being said they're traversing the sibling elements within the tab item pane before considering elements outside that tree so once you set the tabindex you'll find that it goes from tab 1 to tab 2 (which selects it and changes the tab content) to tab 3 which selects it and then since that tab has no children it navigates out to the button.
Ok, using a subclass of XamTabControl as you suggested works. If I set KeyboardNavigation.ControlTabNavigation = "Contained" on the grid inside the TabItemEx, then ctrl-tab cycles through the controls contained in the tab, which is what I want.
Next problem, from the original post: making ctrl-PageUp/Down cycle through tabs. In the OnKeyDown() for XamTabControlEx (the custom subclass), I can select the next tab (when focus is on a control inside the tab, such as one of the checkboxes*), but after that one success, the next ctrl-PageDown event is consumed by XamPager (PART_TabItemScrollViewer), according to Snoop.
(*Ignoring for the time being that the text boxes also eat the ctrl-PageDown)
Am I just asking Infragistics/WPF to bend in a direction it wasn't designed to bend in? I'm on the verge of telling the user "sorry, you're stuck with control tab moving from tab to tab, but we can use it (once) to escape from a text field instead of switching tabs".
(Attaching latest "play" code.)
Just to be clear, you mean if I comment out your handling the PreviewKeyDown (which is reacting to the PageUp/Down)? I don't mean to redirect but xamPager is just a derived ScrollViewer that adds some logic to help it act as a "pager" type control. From looking at their code in ILSpy the ScrollViewer is processing the Next/PageDown and Prior/PageUp keys as long as the Alt key is not pressed. In theory you would think they would only do that if the control key is not pressed but they don't seem to use that info when processing those keys. This is the same reason why you're seeing it not work when the TextBox has focus - because it has a ScrollViewer within it that is processing those keys. While you might be able to do something similar by deriving from ScrollViewer (and retemplating the TextBox to use your derived control) and deriving from XamPager (and retemplating the xamTabControl to use that) it seems like you're probably better off handling the Control+PageDown|Up in a Preview event as you are in the sample you attached (except checking the modifier keys to ensure that Control is down and marking the event as handled so the focused control won't also process it).
Hi, Andrew,
There is a HandlePreviewKeyDown() in the code-behind, but it's not actually hooked up to anything, so commenting it out would do nothing (since it's already effectively commented out). Is that what you're referring to? (Sorry, the code's kind of grown as I played around with it, and there's some dead stuff in there.)
Sorry I blamed Infragistics for behavior it inherited from WPF. Bad reflex. :)
Using PreviewKeyDown works but makes me sad (means contained controls don't get a crack at it, which I know is the point, but, still...) but re-templating stuff just to switch some keys around is also sad. Tradeoffs.
Many thanks for your help. Hopefully I won't be back. :)
Maybe I looked at the wrong project but I thought the one you posted last was hooking the PreviewKeyDown to the XamTabControl_PreviewKeyDown method in the MainWindow.xaml. In any case when I blocked that I saw the behavior you described. I'm sorry I couldn't be of more help in terms of getting this to work without the Preview event but unfortunately the intrinsic controls seem to be making some assumptions here. The only other thing I could see doing is try to mark the event handled before the scrollviewer gets it and then marking it unhandled after it but that assumes that the ordering of the static events is consistent. I attached a modified version of the sample that does that.