Hello,
We have a requirement that all the pane's share the same focus scope. This is so that we don't have ribbon contextual groups showing up from multiple logical scopes across different panes that all have focus.
Setting FocusManager.IsFocusScope="False" on the ContentPane resolves this issue for us, however, it introduces a new issue. When the window is floated, you can no longer tab through controls. I have verified this is still an issue in 14.2. Anyone how I might have floated pane's share the same focus scope? I thought maybe overriding GetUIParentCore to return the XamDockManager, but that did not resolve it.
Example xaml that demonstrates the issue:
Hello mikebm,
Thank you for your post!
I have been investigating this issue regarding focus on XamDockManager floating panes, and I have a couple of questions for you. In your description, you mention ribbon contextual groups showing up among multiple logical scopes, but in the sample code you have provided, I am not seeing a ribbon control included. Could you please provide some detail as to where you are using the ribbon control(s) in this case? Also, could you provide some more detail on the behavior you are seeing with the ribbon contextual groups between focused panes?
Regarding the textboxes not being able to be tabbed between when setting FocusManager.IsFocusScope to false, I have been able to reproduce this. I believe this is because when you set IsFocusScope to false for the content pane, it applies to each element in its content as well. This disallows the tab operation, and so you cannot tab through each textbox.
I also found this link to a page about focus operations that may help you: http://blogs.msdn.com/b/visualstudio/archive/2010/03/09/wpf-in-visual-studio-2010-part-3-focus-and-activation.aspx. I encourage you to take a look at it.
Please let me know if you have any other questions or concerns on this matter.
Sincerely,AndrewAssociate DeveloperInfragistics Inc.www.infragistics.com/support
Don't worry about the ribbon groups. It is not issue I need help with. We have an attached behavior that when a control gets focus, it will make a ribbon group visible. When it loses focus, it will hide the ribbon group. By making all the pane's share focus scope, then I can easily track logical focus instead of keyboard focus. The other part to this is we do all our bindings on LostFocus. This means that when the end user clicks save, we have to simulate a lost focus to get the data pushed up. With different focus scopes on the content pane, it makes things much more challenging.
What is interesting about setting the focusscope to false is that it works correctly when not floated. It technically works correctly when floated too, meaning the panes across multiple windows seem to share the same focus scope. The main issue I am trying to solve is the broken tabbing functionality. It works fine if I used XamTextEditor, or XamComboBox, but not with TextBox or ComboBox.
I have already read that MSDN thread. It got me part of the way to my current solution. In order to get the ribbon to work from floated pane's i had to do some similar things to what is in that thread. Handling PreviewGotKeyboardFocus in the ribbon. I also had to explictely set CommandTargets to Keyboard.FocusedElement on all my routed commands. I then had to have my floated pane's route all events up through the XamDockManager.
I wireup to MainDockingManager.ToolWindowLoaded += MainDockingManager_ToolWindowLoaded;
Hello Mike,
After some more research and collaborating with our development team on this matter, it appears that this issue may be getting caused by the RoutedEventDispatcher method. It appears that what is happening is that you are catching every routed event on the window, re-routing it, and then re-raising it. When I tried not re-raising the events, the tab navigation came back. For the time being, I would like you to comment out the rerouting to the RoutedEventDispatcher in your project, and see if the tab navigation issue still persists.
If you are referring to the RaiseEvent call I make above, that was an attempt at fixing the tab navigation issue and routed command issues. Removing it doesn't make a difference.
The original post contains the full xaml (no changes in code behind) that reproduced the issue.
What I didn't understand is why the infragistics tool window wasn't becoming a focus scope. This is the window that gets created by XamDockingManager for the content pane when it gets floated. At this point, I am re-working a lot of our software to just play better with multiple logical focus scopes. There is definitely a lot of magic that seems to be happening under the WPF covers that I am not fully understand, but your above links have definitely helped clear some understanding for me.
I am glad that the links that I had sent have helped to clear up this issue a bit.
After a bit more research, I believe that I have found why the Infragistics tool window does not become a focus scope. This is expected, since the PaneToolWindow that is returned by e.Window in the ToolWindowLoaded event is hosted by an internal window named ToolWindowHostWindow.
Regarding the RaiseEvent call removal not making a difference, I cannot say that I can reproduce that behavior. Using the code you provided, with a small modification to retrieve the ContentPane since I am unsure what your FindChildByType method is doing. If I remove the code that calls the RoutedEventDispatcher completely, the tab navigation comes back. I have attached the sample I have been using to demonstrate. This sample was tested using Infragistics for WPF 2014 Volume 2, specific version 14.2.20142.2081.
I am good, thanks Andrew.
Just checking in, did you have any other questions or concerns on this matter?
Thank you for your response.
I have reproduced the behavior that you have described, but it appears that by removing the FocusManager.SetIsFocusScope(pane, true); line from your ToolWindowLoaded code, you are essentially getting the same effect as in your original post with the FocusManager.IsFocusScope = "False" being set on the ContentPane.
The reason is because when you re-dock the pane in the dock manager, the e.Window.Closed delegate fires, setting the ContentPane's focus scope to false. When you float the pane, the ToolWindowLoaded event fires again for the new window, but the ContentPane is still the same pane. Since the FocusManager.SetIsFocusScope(pane, true); is now removed, the FocusManager.IsFocusScope property remains false when the pane is floated, and so the tab navigation is disabled.
I would recommend that you leave the FocusManager.SetIsFocusScope(pane, true) code in your ToolWindowLoaded event if you wish to keep the tab navigation enabled in this case.
Hi Andrew,
The reason your example works is because you have my workaround code in place which is to re-enable the focus scope on the pane when floated. When unfloated, they all share the same focus scope, when floated, I had to re-enable the focus scope so that tab navigation works. This is being done by the following line:
FocusManager.SetIsFocusScope(pane, true);
Get rid of that, and your tab navigation will stop.