Handling of Tab Key in C#(WPF) VisualPlugin

We have a .NET plugin descending from RemObjects.Hydra.WPF.VisualPlugin with a plugin wrapper descending from RemObjects.Hydra.WPF.Internal.VisualPluginWrapper as described in http://wiki.remobjects.com/wiki/Passing_interfaces_between_Host_and_Plugins. The plugin is hosted in a Delphi application.

When Tab key is processed in the plugin, the focus does not work as expected. First, the tab order seems to be rather random, depending on how the TabIndex property is set on the control gaining and loosing focus. Secondly, we are not able to tab correctly out of the Plugin and into the other controls in the hosting Delphi Form. Both problems seems to have its source in the way the tab order is calculated in the VisualPlugin base class.

Decompiled source where the errors seems to be located:

protected virtual bool ChildSelectNextControl(bool aForward)
{
  bool flag = false;
  TraversalRequest request = new TraversalRequest(!aForward ? FocusNavigationDirection.Previous : FocusNavigationDirection.Next);
  DependencyObject element = (DependencyObject) Keyboard.FocusedElement;
  if (element is UIElement)
    flag = ((UIElement) element).MoveFocus(request);
  else if (element is ContentElement)
    flag = ((ContentElement) element).MoveFocus(request);
  if (flag)
  {
    int tabIndex1 = KeyboardNavigation.GetTabIndex(element);
    int tabIndex2 = KeyboardNavigation.GetTabIndex((DependencyObject) Keyboard.FocusedElement);
    if (((tabIndex2 >= tabIndex1 ? 0 : (aForward ? 1 : 0)) == 0 ? (tabIndex2 <= tabIndex1 ? 0 : (!aForward ? 1 : 0)) : 1) != 0)
      flag = false;
  }
  return flag;
}

By browsing the decompiled source for the class, it appears that in the method ChildSelectNextControl, the entire logic on tab order of the elements are based on an assumption that all controls are positioned within the same parent, and that the TabIndex property has been set on all controls. However, the TabIndex property is relative to the parent control (and not the global order in the plugin) so the algorith fails. Another fact is that when the TabIndex property is not set (has the value int.MaxValue) it is not possible to calculate tab order using this method.

The bottom line seems to be that the “flag” variable seems to be calculated wrong when having a mix of controls with and without valid TabIndex, and also with controls placed within different parent controls.

A way to solve this matter would be to generate a list of all controls that can be focused and find out from this list which control is first in the (global) tab order in the VisualPlugin.

Kind regards,
Henrik

Thank you for the report, logged as #53823 for review.

However you are right, since WPF does not provide any methods that works with the focus, we using a TabIndex to determine the tab order of elements.