Major focus issue when switching tabs

4 posts, 1 answers
  1. Sam
    Sam avatar
    67 posts
    Member since:
    Jun 2011

    Posted 08 Aug 2012 Link to this post


    Hi there, we're experiencing some very strange behaviour with RadTabControl (Q2 2012 SP1 version).

    We have a tab control with 4 tabs, when the user clicks the last tab, the first control (a TextBox) inside the tab item content is focussed automatically, which is completely against what we want to happen.

    I've had a look at the disassembled source for RadTabControlBase, and it appears there is some code in there (UpdateFocusOnSelectionChange) that does exactly what is happening - the first enabled / visible control inside the new tab content is focussed directly:

          protected internal virtual void UpdateFocusOnSelectionChange()
        {
          if (!this.IsUserInitiatedSelection)
            return;
          IRadTabItem selectedContainer = this.GetSelectedContainer();
          if (selectedContainer == null)
            return;
          DependencyObject descendant = (DependencyObject) (this.GetFocusedElement() as UIElement);
          ContentPresenter currentContentElement = this.GetCurrentContentElement();
          bool shouldFocusContent = descendant == null || currentContentElement != null && ParentOfTypeExtensions.IsAncestorOf((DependencyObject) currentContentElement, descendant) || !ParentOfTypeExtensions.IsAncestorOf((DependencyObject) this, descendant);
          this.Dispatcher.BeginInvoke((Action) (() =>
          {
            if (shouldFocusContent)
            {
              Control local_0 = currentContentElement == null ? (Control) null : ChildrenOfTypeExtensions.GetFirstDescendantOfType<Control>((DependencyObject) currentContentElement);
              if (local_0 == null)
              {
                FrameworkElement local_1 = this.SelectedContent as FrameworkElement;
                local_0 = local_1 != null ? ChildrenOfTypeExtensions.GetFirstDescendantOfType<Control>((DependencyObject) local_1) : (Control) null;
              }
              if (local_0 == null)
                return;
              local_0.Focus();
            }
            else
              selectedContainer.Control.Focus();
          }));
        }


    I would like to know if there is a way that I can stop this from happening, and why it's happening in the first place.

    Thanks,

    Sam
  2. Answer
    Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 13 Aug 2012 Link to this post

    Hi Sam,

    You are absolutely right about the code fragment. The UpdateFocusOnSelectionChange method decides which element should be focused. If the focus is outside the TabControl or inside the selected content, selecting a new TabItem will move the focus to the first focusable child in the newly selected content.
    This is done in order to be consistent with the WPF TabControl and provide better user experience.

    If you want to disable this behavior you could simply move the focus to the TabControl itself after the selection has been changed. I'm attaching a sample project demonstrating the approach. The key part is to use a dispatcher because the focus operation is asynchronous one and should happen after the selection change logic has been processed.

    Hope this helps.

    Kind regards,
    Hristo
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

  3. DevCraft banner
  4. Sam
    Sam avatar
    67 posts
    Member since:
    Jun 2011

    Posted 13 Aug 2012 Link to this post


    Hi Hristo, thanks for the sample, this workaround is fine.

    However I really think you should make this focus behaviour configurable, via a new Boolean property or something similar, so that it can be switched off if users don't want it (like us). You could still leave it on by default.

    Adding event handlers to all our rad tab controls is a little heavy - it would be much easier if we could just set something once in a style.

    Thanks for the help,

    Sam
  5. Hristo
    Admin
    Hristo avatar
    352 posts

    Posted 14 Aug 2012 Link to this post

    Hello Sam,

    First of all I would like to thank you for sharing your feedback with us.
    You are absolutely right about setting the event to every TabControl in the application is heavy and bulky. Using a style would be much more convenient way to do that and we will take you suggestion into consideration.  

    I would like to offer you a workaround to the bulky approach and eliminate the duplicated code.
    You could created an attached behavior that is registering the event handler and set this behavior in the style for every TabControl you would like to behave in the modified mode (not moving the focus after selection).
    The following forum post describes the approach I have in mind: http://forums.silverlight.net/t/171651.aspx/1.

    Greetings,
    Hristo
    the Telerik team

    Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Back to Top