98

Despite some posts on this forum and others i cannot find something that tells me how to set the focus on a TextBox.

I have a userControl with many labels and textBoxes. When the form is loaded I want the a particular textBox to have the focus.

I have set the tabIndex but that didn't seem to work.

Any suggestions?

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
user9969
  • 15,632
  • 39
  • 107
  • 175

10 Answers10

189

You can use the FocusManager.FocusedElement attached property for this purpose. Here's a piece of code that set the focus to TxtB by default.

<StackPanel Orientation="Vertical" FocusManager.FocusedElement="{Binding ElementName=TxtB}">
    <TextBox x:Name="TxtA" Text="A" />
    <TextBox x:Name="TxtB" Text="B" />
</StackPanel>

You can also use TxtB.Focus() in your code-behind if you don't want to do this in XAML.

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
  • 14
    @TarkaDaal: the "it didn't work for me" comment could be a little more elaborated. It's probably another control stealing the focus. When the focus war begins in WPF, things tend to go naughty! Please verify your controls, and where you are currently in the visual tree (for example, inside a ComboBox template, this will have no effect, and there are numerous other cases like this). If you can't find the stealer, use a behavior or code-behind to set the focus to the control when its loaded. – Julien Lebosquain Jan 24 '13 at 19:08
  • @JulienLebosquain: It was a pretty simple control, two buttons and a TextBox within a Grid (which is where I put the `FocusManager` stuff). In the end, I did it in the code-behind. – TarkaDaal Jan 25 '13 at 08:44
  • The member "FocusedElement" is not recognized or is not accessible. :( https://plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/5991104640269523954 – Hendy Irawan Mar 15 '14 at 19:46
  • @HendyIrawan Is that a Silverlight project, maybe? – MojoFilter May 19 '14 at 13:14
  • @MojoFilter it's a Windows Phone 8 WPF project – Hendy Irawan May 20 '14 at 16:08
  • 1
    I'm using WPF 4.5. FocusManager.FocusedElement does absolutely nothing. Am I missing something? – Jordan Jan 14 '15 at 16:48
  • There seems to be a minor issue if the stackpanel is inside a TreeView, but this worked fine for our NuGet Package Explorer customisation. Thanks :) – iCollect.it Ltd Jul 27 '15 at 11:24
  • Works for me in a Grid. – MetalMikester Sep 01 '16 at 13:46
  • In my case this it doesn't work, nor does the solution from Max work. I see the TextBox focused but typing doesn't work until i click on the TextBox. It might have to do with the fact that I change the visibility of the container of the TextBox. – r41n Nov 30 '16 at 15:29
  • (+1) Thanks. As a note, it works when using FocusManager.FocusedElement in a control like StackPanel, Grid etc. but does not work when I used it in the Window properties. But this is not a problem. – Mustafa Özçetin Dec 23 '22 at 06:53
27

You can apply this property directly on the TextBox :

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Max
  • 1,810
  • 3
  • 26
  • 37
7

I am new to using WPF and reading through the above examples I had a similar experience trying set the focus to a textbox using the xaml code examples given, i.e. all the examples above didn't work.

What I found was I had to place the FocusManager.FocusElement in the page element. I assume this would probably work as well if you used a Window as the parent element. Anyway, here is the code that worked for me.

 <Page x:Class="NameOfYourClass"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  mc:Ignorable="d"
  Title="Title" 
  Height="720"
  Width="915"
  Background="white"
  Loaded="pgLoaded"
  FocusManager.FocusedElement="{Binding ElementName=NameOfYourTextBox}">

  <!-- Create child elements here. -->

  </Page>
Joseph Mawer
  • 288
  • 6
  • 16
2

I have a TextBox inside a Grid inside a DataTemplate which I want to have keyboard focus when it becomes visible. I also found that

<DataTemplate x:Key="DistanceView" DataType="{x:Type vm:ROI}">
    <Grid FocusManager.FocusedElement="{Binding ElementName=tbDistance}">
        <TextBox x:Name="tbDistance" Grid.Column="1" Grid.Row="1" VerticalAlignment="Bottom"/>
    </Grid>
</DataTemplate>

did not work for me.

However when I call Focus() in the parent ContentControl

private void ContentControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if ((sender as ContentControl).IsVisible)
    {
        (sender as ContentControl).Focus();
    }
}

it starts to work and the caret is visible in the TextBox. I think the FocusScope has to be given focus for the FocusManager.FocusedElement property to have any effect.

Jerry

Jerry
  • 393
  • 4
  • 8
  • Nice solution. This is what I had to do as none of the other answer methods seemed to work. In my case I had a set of tabbed forms, and needed to set the focus when a tab became visible. – Tim Holt Apr 22 '21 at 19:44
1

From experimenting around, the xaml solution

FocusManager.FocusedElement="{Binding ElementName=yourElement}"

seems to work best when you place it in the highest element in the window hierarchy (usually Window, or the Grid you place everything else in)

Tan Jing Yuan
  • 73
  • 2
  • 7
1

Usage: local:FocusManager.FocusOnLoad="True"

    public class FocusManager
    {
        public static readonly DependencyProperty FocusOnLoad = DependencyProperty.RegisterAttached(
            "FocusOnLoad",
            typeof(bool),
            typeof(FocusManager),
            new UIPropertyMetadata(false, new PropertyChangedCallback(OnValueChanged))
            );

        private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            if (!(sender is Control control))
                return;

            if ((bool) e.NewValue == false)
                return;

            control.Loaded += (s, e) => control.Focus();
        }

        public static bool GetFocusOnLoad(DependencyObject d) => (bool) d.GetValue(FocusOnLoad);

        public static void SetFocusOnLoad(DependencyObject d, bool value) => d.SetValue(FocusOnLoad, value);
    }
SERKAN
  • 11
  • 1
  • 2
0

FocusManager was not in intellisense and this confused me a bit. I just typed the entire attribute and it worked.

FocusManager.FocusedElement="{Binding ElementName=MyTextBox}"


Microsoft Visual Studio Enterprise 2015 version 14.0.23107.0/C#/WPF

icernos
  • 395
  • 3
  • 6
0

For completeness, there is also a way to handle this from code behind (e.g. in the case of controls that, for whatever reason, are created dynamically and don't exist in XAML). Attach a handler to the window's Loaded event and then use the ".Focus()" method of the control you want. Bare-bones example below.

public class MyWindow
{
    private VisualCollection controls;
    private TextBox textBox;

    // constructor
    public MyWindow()
    {
        controls = new VisualCollection(this);
        textBox = new TextBox();
        controls.Add(textBox);

        Loaded += window_Loaded;
    }

    private void window_Loaded(object sender, RoutedEventArgs e)
    {
        textBox.Focus();
    }
}
Robert N
  • 1,156
  • 2
  • 14
  • 32
  • This does work, but bear in mind that the event never gets unhooked, which will prevent the class from being disposed, which is a potential memory leak. – Dave Feb 04 '22 at 12:46
  • (To be correct I should have said "garbage collected" not "disposed") – Dave Feb 04 '22 at 14:23
-1

bind the element you want to point the focus in as

FocusManager.FocusedElement= "{Binding ElementName= Comobox1}"

in grid or groupbox etc

Hamad
  • 5,096
  • 13
  • 37
  • 65
-1

Further to my comment on Feb 04 '22, I solved it this way:

In the UserControl definitionin the XAML add a Loaded event handler. (pressing tab after Loaded= will automatically add an event handler to the code behind)

Then edit the event handler in the code behind:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
    expressionTextBox.Focus();
}

I'm hoping that WPF is clever enough to handle th unhooking of the evnt at some point, allowing the class to be garbage collected and not give rise to memory leaks, but I don't know. I'd be interested in any comments on that.

Dave
  • 3,429
  • 2
  • 26
  • 29