Set the focus on a TextBox in WPF XAML
Asked Answered
G

10

100

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 a particular TextBox to have the focus.

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

Any suggestions?

Gagarin answered 20/5, 2010 at 8:54 Comment(1)
Possible duplicate of WPF and initial focusWetzell
I
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.

Infrared answered 20/5, 2010 at 9:4 Comment(10)
@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.Infrared
@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.Melitamelitopol
The member "FocusedElement" is not recognized or is not accessible. :( plus.google.com/photos/+HendyIrawan/albums/5990385944888867505/…Harding
@HendyIrawan Is that a Silverlight project, maybe?Francophile
@Francophile it's a Windows Phone 8 WPF projectHarding
I'm using WPF 4.5. FocusManager.FocusedElement does absolutely nothing. Am I missing something?Reticle
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 :)Farfetched
Works for me in a Grid.Interest
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.Aq
(+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.Ascendant
T
27

You can apply this property directly on the TextBox :

<TextBox Text="{Binding MyText}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"/>
Thermolysis answered 12/4, 2013 at 13:35 Comment(8)
Didn't work for me, setting FocusManager.FocusedElement="{Binding ElementName=TxtB}" on the container did workHawes
Works like a charm and does not require any namings.Dar
Did not work for me as well. Are we missing something?Chitchat
I don't know why this Binding doesn't work for some people or project. Maybe asking a new question with a code sample could be interesting.Thermolysis
Didn't work for me either. Suggestion by Julien Lebosquain work.Basin
Doesn't work for me either. All other methods proposed also not working. This problem must be elementary and should be solvable eeeasily.. That's why many ppl don't like wpf.Petronia
Could you please explain why does this binding work? Thanks!Prokopyevsk
Hello from 2020! The suggestion doesn't work for me either.Extensor
U
8

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>
Unexpected answered 13/1, 2017 at 21:23 Comment(0)
A
3

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

Aphyllous answered 5/8, 2020 at 12:7 Comment(1)
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.Gonion
C
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)

Cain answered 26/1, 2019 at 15:26 Comment(1)
Interesting observation. Maybe this can explain why there are so many other failures reported here.Veery
E
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);
    }
Euh answered 8/4, 2020 at 12:50 Comment(0)
K
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

Knit answered 8/6, 2016 at 19:48 Comment(0)
G
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();
    }
}
Gorgonian answered 9/11, 2016 at 23:1 Comment(2)
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.Perichondrium
(To be correct I should have said "garbage collected" not "disposed")Perichondrium
G
-1

bind the element you want to point the focus in as

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

in grid or groupbox etc

Granulite answered 31/10, 2014 at 11:57 Comment(4)
Uhh yeah, thanks for giving the same answer everyone else did ... 4 years later...Riviera
@AdamPlocher Nice one, you put Sulfian off Stack Overflow permanently. A "Welcome to Stack overflow" message would have been more appropriate.Girard
@Contango: "Last seen Nov 11 '14". He was long gone before Adam posted his comment :)Farfetched
Voting down because it is a duplicate of the accepted and most upvoted answer, so it would be better if this disappears.Veery
P
-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.

Perichondrium answered 4/2, 2022 at 14:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.