How can I prevent tabbing to a UserControl?
Asked Answered
D

6

14

I have a custom Popup that overlays part of my screen. When it is open, I want to disable tabbing into the UserControl behind it. I do not want to use the IsEnabled property because I do not want to gray out all the controls.

Is there another property that does the same thing? IsTabStop only prevents the tab from stopping on the UserControl itself, not it's children, and IsFocusable isn't a valid property for a UserControl.

Dorcasdorcea answered 12/10, 2011 at 19:21 Comment(5)
Focusable is a property on UserControl inherited from UIElement. Setting Focusable="False" and IsHitTestVisible="False" should solve your problemPurington
@Meleak That does not work. I can still tab to the controls inside my UserControlDorcasdorcea
Does KeyboardNavigation.TabNavigation="None" on your UserControl help? Have a look hereResponsory
@Responsory I take it back, that does work :) I was setting my KeyBoardNavigation.TabNavigation inside my UserControl, so the trigger was having no effect. If you post it as an answer I'll accept it.Dorcasdorcea
IsTabStop seems to not work on user controls that have ItemsSource assigned. See thisBowknot
R
23

Use the KeyboardNavigation.TabNavigation Attached Property with KeyboardNavigationMode.None on your container control.

KeyboardNavigation.TabNavigation="None"
Responsory answered 13/10, 2011 at 18:0 Comment(0)
F
6

You can bind IsTabStop on the child controls to IsTabStop on the UserControl.

That way, you only have to set it once.

Fordone answered 12/10, 2011 at 19:35 Comment(3)
I currently have 35 controls in my UserControl... I don't really want to create a binding on all of them, and have to remember to set that binding for new controls. Isn't there an easier way of disabling it on the UserControl level?Dorcasdorcea
A loop? foreach (Control control in grid.Children) { control.IsTabStop = false; }Basswood
It'd have to be a loop that goes through all levels of child objects.... I suppose it's possibleDorcasdorcea
G
0

You could write an attached property that you would set in the top element.
That attached property would recursively set IsTabStop to false in all the child elements.

Let me know if you need any help getting this to work.

Gelderland answered 12/10, 2011 at 22:35 Comment(0)
V
0

Just bind that property to the user control.

    <UserControl x:Class="PDV.UserControls.InputField"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 // etc... then:                     
                 x:Name="Root" KeyboardNavigation.TabNavigation="Local" >

        <Grid>
           <TextBox Name="textBox"  
                TabIndex="{Binding Path=TabIndex, ElementName=Root}" 
                IsTabStop="{Binding Path=IsTabStop, ElementName=Root}"  />                
        </Grid>
    </UserControl>
Vasiliki answered 16/4, 2012 at 12:24 Comment(0)
A
0

The solution with KeyboardNavigation.TabNavigation="None" seems to bubble up to all other parent containers in my case. This is maybe not wanted in some scenarios. So I came up with a PreviewKeyDown-Event in code behind like this:

    private void OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Tab)
        {
            ((Control)sender).Focus(); 
            e.Handled = true;
        }
    }
Apatetic answered 3/2, 2020 at 8:58 Comment(0)
C
0

This worked for me:

// ...

var applicationWindow = Application.Current?.MainWindow;
if (applicationWindow != null)
{
    KeyboardNavigation.SetIsTabStop(
        element: applicationWindow, 
        isTabStop: false);

    KeyboardNavigation.SetTabNavigation(
        element: applicationWindow, 
        mode: false);
}

// ...

Note: it is good to have a backup plan for restoring the Keyboard navigation in case if the above is needed only temporarily.

Cry answered 8/12, 2020 at 15:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.