Page 1 of 1

FocusManager Focus Scope For Tab Control

Posted: 07 Jan 2025, 16:36
by aivanov
Is it possible to use FocusManager.IsFocusScope="True" to manage focus on separate tabs of a tab control? Ideally, each tab would remember which element most recently had focus and return focus to this element when the tab is visible again. Testing locally, focus doesn't seem to be updating when the tabs are switched. I have also tried moving the FocusManager.IsFocusScope property to the inside of the CustomControlTab1 (onto the UserControl, the root grid, and the stack panel) without any luck.

Am I missing something? Is there a better way to do this?
<TabControl x:Name="MyTabControl" SelectedIndex="{Binding ActiveTabIndex}">
	<TabItem x:Name="Tab1">
		<local:CustomControlTab1 FocusManager.IsFocusScope="True"/>
	</TabItem>
	<TabItem x:Name="Tab2">
		<local:CustomControlTab2 FocusManager.IsFocusScope="True"/>
	</TabItem>
	<TabItem x:Name="Tab3">
		<local:CustomControlTab3 FocusManager.IsFocusScope="True"/>
	</TabItem>
	<TabItem x:Name="Tab4">
		<local:CustomControlTab4 FocusManager.IsFocusScope="True"/>
	</TabItem>
</TabControl>
<UserControl
	x:Class="CustomControlTab1"
>
	<Grid x:Name="Root" Width="1700">
        
		<ScrollViewer x:Name="Container" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabNavigation="Contained" KeyboardNavigation.ControlTabNavigation="Contained">
			<StackPanel>
				<!-- various focusable elements arranged vertically -->
			</StackPanel>
		</ScrollViewer>
	</Grid>
</UserControl>

Re: FocusManager Focus Scope For Tab Control

Posted: 08 Jan 2025, 05:17
by KeldorKatarn
Focus scopes are a bit of a badly documented feature.

There is an old article about this in WPF that should give you the information on why this doesn't work and what you need to make it work:

https://www.codeproject.com/Articles/38 ... FocusScope

Re: FocusManager Focus Scope For Tab Control

Posted: 09 Jan 2025, 17:59
by aivanov
I am doing my best to follow along with what the site is suggesting but I am still having trouble getting focus to be stored on individual tabs. The issue seems to be that UIElement references become invalid after tabs change and so we never successfully set focus when we return to the tab.

Is there any way to store a reference to the currently focused UIElement without it going to null?

Below is the code behind for the UserControl within one of the tab items. The Xaml of this UserControl also has "FocusManager.IsFocusScope="True"" set:
<UserControl 
     <!-- some other things -->
     x:Class="CustomControlTab1"
     FocusManager.IsFocusScope="True"
>
public class OverlayBaseControl : UserControl
    {
        private UIElement _lastFocusedElement;

        public OverlayBaseControl()
        {
            WeakReference weak = new WeakReference(this);
            this.GotKeyboardFocus += GotKeyboardFocusHandler;
            this.Loaded += ScreenLoaded;
        }

        public void ScreenLoaded(object sender, Noesis.EventArgs eventArgs)
        {
            UIElement storedFocus = FocusManager.GetFocusedElement(this);
            if (storedFocus != null)
            {
                // This code is never executed, storedFocus is always null
                Keyboard.Focus(storedFocus);
                storedFocus.Focus();
            }
        }

        public void GotKeyboardFocusHandler(object sender, KeyboardFocusChangedEventArgs eventArgs)
        {
            _lastFocusedElement = eventArgs.NewFocus;
            // ^^ new focus in not null at this point
            for (DependencyObject d = _lastFocusedElement as DependencyObject; 
                 d != null; d = VisualTreeHelper.GetParent(d)) {
                if (FocusManager.GetIsFocusScope(d)) {
                    d.SetValue(FocusManager.FocusedElementProperty, _lastFocusedElement);
                    if (d is not OverlayBaseControl)
                    {
                        break;
                    }
                }
            }
        }

Re: FocusManager Focus Scope For Tab Control

Posted: 14 Jan 2025, 10:51
by sfernandez
The problem is not on your side, we have something going wrong with the TabControl/TabItem logic in relation with focus scopes.
In theory it should be as easy as setting IsFocusScope to true on the TabItems and going from one tab to another it should restore the latest focused element in the tab.

Could you please create a ticket about it in our bugtracker?

Re: FocusManager Focus Scope For Tab Control

Posted: 14 Jan 2025, 21:18
by aivanov

Re: FocusManager Focus Scope For Tab Control

Posted: 17 Jan 2025, 06:11
by KeldorKatarn
The problem is not on your side, we have something going wrong with the TabControl/TabItem logic in relation with focus scopes.
In theory it should be as easy as setting IsFocusScope to true on the TabItems and going from one tab to another it should restore the latest focused element in the tab.

Could you please create a ticket about it in our bugtracker?
Won't using the regular IsFocusScope property cause the same issue it does on WPF, i.e. RoutedCommands getting lost? See the link I provided?
I've had this issue many times in WPF. isFocusScope on WPF is not really a user feature. It was used by the developers for toolbars and menus.