How to automatically select all text on focus in WPF TextBox?
Asked Answered
L

35

267

If I call SelectAll from a GotFocus event handler, it doesn't work with the mouse - the selection disappears as soon as mouse is released.

EDIT: People are liking Donnelle's answer, I'll try to explain why I did not like it as much as the accepted answer.

  • It is more complex, while the accepted answer does the same thing in a simpler way.
  • The usability of accepted answer is better. When you click in the middle of the text, text gets unselected when you release the mouse allowing you to start editing instantly, and if you still want to select all, just press the button again and this time it will not unselect on release. Following Donelle's recipe, if I click in the middle of text, I have to click second time to be able to edit. If I click somewhere within the text versus outside of the text, this most probably means I want to start editing instead of overwriting everything.
Log answered 18/3, 2009 at 23:54 Comment(6)
If you are going to have more than one form, her answer continues to become less complex than the first. Usability of both options is moot as you can change how either of them work.Interclavicle
@Sergey: You may want to change the accepted answer for this question, as there have been better answers since. I'm not going to suggest mine, but you could ;)Berndt
Question has Silverlight tag, yet Silverlight doesn't have most of events / any kind of preview events at all. Which solution should be used for silverlight then?Seeing
Link "Why is focus in WPF so tricky?" is brokenSpracklen
as mentioned in a comment on https://mcmap.net/q/108718/-how-to-automatically-select-all-text-on-focus-in-wpf-textbox below, madprops.org/blog/wpf-textbox-selectall-on-focus is an easy solution and preserves the original nouse behaviour. I put the event registration in the constructor because I only have one WPF control in the app.Uroscopy
stackoverflow.com/questions/31291770Nelsen
C
91

Don't know why it loses the selection in the GotFocus event.

But one solution is to do the selection on the GotKeyboardFocus and the GotMouseCapture events. That way it will always work.

-- Edit --

Adding an example here to show people how to work around some the mentioned drawbacks:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    // Fixes issue when clicking cut/copy/paste in context menu
    if (textBox.SelectionLength == 0) 
        textBox.SelectAll();
}

private void TextBox_LostMouseCapture(object sender, MouseEventArgs e)
{
    // If user highlights some text, don't override it
    if (textBox.SelectionLength == 0) 
        textBox.SelectAll();

    // further clicks will not select all
    textBox.LostMouseCapture -= TextBox_LostMouseCapture; 
}

private void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    // once we've left the TextBox, return the select all behavior
    textBox.LostMouseCapture += TextBox_LostMouseCapture;
}
Comprehension answered 19/3, 2009 at 0:27 Comment(7)
Nope. When clicked with the mouse in the middle of existing text - selection is lost as soon as mouse button is released.Log
Though - after a second single click, it selects all text again... Not sure if it is an intended behavior from WPF designers, but usability is not that bad. Another difference from a single GotFocus handler is that clicking on an empty space in the TextBox does select all.Log
This was my fist solution, too. But I found that users are really annoyed, when they're unable to select Text using the Mouse, because everytime they click the whole text gets selected...Asclepiadaceous
One further drawback of this solution is when you use the TextBox's "Cut/Copy/Paste" menu, the whole text is selected when you select any menu item.Francie
@Comprehension I know this is old, but does anyone know why in the GotFocus event the selected text is lost? You're right about it working in other events, though and that's a perfectly acceptable solution in my book.Ridgway
Is there any solution?Biblical
Using the LostMouseCapture event instead works for me...Millicent
F
224

We have it so the first click selects all, and another click goes to cursor (our application is designed for use on tablets with pens).

You might find it useful.

public class ClickSelectTextBox : TextBox
{
    public ClickSelectTextBox()
    {
        AddHandler(PreviewMouseLeftButtonDownEvent, 
          new MouseButtonEventHandler(SelectivelyIgnoreMouseButton), true);
        AddHandler(GotKeyboardFocusEvent, 
          new RoutedEventHandler(SelectAllText), true);
        AddHandler(MouseDoubleClickEvent, 
          new RoutedEventHandler(SelectAllText), true);
    }

    private static void SelectivelyIgnoreMouseButton(object sender, 
                                                     MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focussed, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    private static void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
Fidelfidela answered 19/3, 2009 at 6:18 Comment(7)
I have updated the question explaining why the selected answer is still better.Log
I saw a nearly identical answer here social.msdn.microsoft.com/Forums/en-US/wpf/thread/…, it works as well, how ever it doesn't uses e.OriginalSource, nor crawls through the visual tree. Is there any advantage on doing all this?Maquis
Works great, but would be perfect if it still allowed drag-selection of text with the mouse. The Google Chrome address bar is a perfect example of the ideal system: if the user clicks and releases without dragging, the entire text is highlighted. However if the user clicks and drags, the drag selects text normally without selecting all. The SelectAll only occurs on mouse release. I will fiddle and see if I can improve this design at all.Jaclin
One further drawback of this solution is when you use the TextBox's "Cut/Copy/Paste" menu, the whole text is selected when you select any menu item.Francie
I found that an additional test in the SelectAllText method of textBox.IsFocused improves it. You don't want to select all when the GetKeyboardFocus is due to alt-tabbing into the program.Marlowe
I just wish there were better ways to modify how normal work without having to inherit and override in a subclass.Pocahontas
This breaks datagrid, when used in DataGridTemplateColumn without CellEditTemplate. Clicking on a textbox in a different datagrid row will not select that row anymore. The reason for this is the handling of the PreviewMouseDown event. Every other solution using this event, will have the same problem.Corelative
B
184

Donnelle's answer works the best, but having to derive a new class to use it is a pain.

Instead of doing that I register handlers the handlers in App.xaml.cs for all TextBoxes in the application. This allows me to use a Donnelle's answer with standard TextBox control.

Add the following methods to your App.xaml.cs:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e) 
    {
        // Select the text in a TextBox when it receives focus.
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
            new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
            new RoutedEventHandler(SelectAllText));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
            new RoutedEventHandler(SelectAllText));
        base.OnStartup(e); 
    }

    void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        // Find the TextBox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        if (parent != null)
        {
            var textBox = (TextBox)parent;
            if (!textBox.IsKeyboardFocusWithin)
            {
                // If the text box is not yet focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}
Berndt answered 31/3, 2010 at 13:32 Comment(7)
This is a pretty cool solution, it was also described by Matt Hamilton ages ago here: madprops.org/blog/wpf-textbox-selectall-on-focusAstraea
Question has Silverlight tag, yet Silverlight doesn't have most of events / any kind of preview events at all. Which solution should be used for silverlight then? thanks in advanceSeeing
Best answer on the internet.Kenlay
FAN - FREAKING - TASTIC. Thank you for this. I wish I could upvote this 255 times.Rhoden
"The spelling focused is much more common in the US; however, the spelling focussed is sometimes used in the UK and Canada, and is especially common in Australia and New Zealand." So nyah ;)Fidelfidela
This is the best answer!Ruckman
Just like @Francie said about @Grokys?'s (currently Accepted) A above from "Mar 31 '10 at 13:32": "One further drawback of this solution is when you use the TextBox's (default Context Menu, i.e.) Cut/Copy/Paste menu, the whole text is selected when you select any menu item.". I'd prefer not to have to use create/use a different Class in every app/for every TextBox Instance or worse, add Event Handlers every TextBox Instance, so this is my fav A. Any ideas how to avoid that drawback?Comenius
A
103

I have chosen part of Donnelle's answer (skipped the double-click) for I think this a more natural. However, like Grokys I dislike the need to create a derived class. But I also don't like Grokys' OnStartup method. And I need this on a "generally but not always" basis.

I have Implemented this as an attached DependencyProperty so I can set local:SelectTextOnFocus.Active = "True" in xaml. I find this way the most pleasing.

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;

public class SelectTextOnFocus : DependencyObject
{
    public static readonly DependencyProperty ActiveProperty = DependencyProperty.RegisterAttached(
        "Active",
        typeof(bool),
        typeof(SelectTextOnFocus),
        new PropertyMetadata(false, ActivePropertyChanged));

    private static void ActivePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is TextBox)
        {
            TextBox textBox = d as TextBox;
            if ((e.NewValue as bool?).GetValueOrDefault(false))
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
        {
            return;
        }

        var textBox = (TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        TextBox textBox = e.OriginalSource as TextBox;
        if (textBox != null)
        {
            textBox.SelectAll();
        }
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetActive(DependencyObject @object)
    {
        return (bool) @object.GetValue(ActiveProperty);
    }

    public static void SetActive(DependencyObject @object, bool value)
    {
        @object.SetValue(ActiveProperty, value);
    }
}

For my "general but not always" feature I set this Attache Property to True in a (global) TextBox Style. This way "selecting the Text" is always "on", but I can disable it on a per-textbox-basis.

Asclepiadaceous answered 20/4, 2010 at 10:32 Comment(9)
+1 this is much better than setting it globally, and it's more 'the WPF way' than deriving from TextBox.Pazit
Solid answer. Attached properties are very nice.Discoverer
+1 Agree with stijn. "Hiding" your code in the app.cs is not nice for the poor dev who has to figure out why SelectAllOnFocus is happening. :-) I just dropped this into my class for TextBoxBehaviors and then updated my base TextBox Style. Worked a treat. CheersBasilius
How do you add this in the Global TextBox style?Kendricks
@tronda: Simply add a style to the resources using a TargetType of TextBox. I suggest you have a look at wpftutorial.net/Styles.htmlAsclepiadaceous
I agree this is better than my answer! +1Berndt
Another +1 for the best answer. Only problem I find is that the text is always selected even when I use the right mouse button - which I frequently do to edit the text via context menu - the solution does not work for this case because it always selects all the text even if I just wanted to cut 1 word via context menu. Do you guys know how to fix this?Elan
I like this answer but why do you have to extend DependencyObject? I removed that and it still works fine.Ruin
@Ruin I agree - it is only necessary to derive from DependencyObject if you want ordinary DependencyProperties for that class, not to make attached properties that apply to other classes (which already must be derived from DependencyObject). Furthermore, the entire class could be static.Headword
C
91

Don't know why it loses the selection in the GotFocus event.

But one solution is to do the selection on the GotKeyboardFocus and the GotMouseCapture events. That way it will always work.

-- Edit --

Adding an example here to show people how to work around some the mentioned drawbacks:

private void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    // Fixes issue when clicking cut/copy/paste in context menu
    if (textBox.SelectionLength == 0) 
        textBox.SelectAll();
}

private void TextBox_LostMouseCapture(object sender, MouseEventArgs e)
{
    // If user highlights some text, don't override it
    if (textBox.SelectionLength == 0) 
        textBox.SelectAll();

    // further clicks will not select all
    textBox.LostMouseCapture -= TextBox_LostMouseCapture; 
}

private void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
    // once we've left the TextBox, return the select all behavior
    textBox.LostMouseCapture += TextBox_LostMouseCapture;
}
Comprehension answered 19/3, 2009 at 0:27 Comment(7)
Nope. When clicked with the mouse in the middle of existing text - selection is lost as soon as mouse button is released.Log
Though - after a second single click, it selects all text again... Not sure if it is an intended behavior from WPF designers, but usability is not that bad. Another difference from a single GotFocus handler is that clicking on an empty space in the TextBox does select all.Log
This was my fist solution, too. But I found that users are really annoyed, when they're unable to select Text using the Mouse, because everytime they click the whole text gets selected...Asclepiadaceous
One further drawback of this solution is when you use the TextBox's "Cut/Copy/Paste" menu, the whole text is selected when you select any menu item.Francie
@Comprehension I know this is old, but does anyone know why in the GotFocus event the selected text is lost? You're right about it working in other events, though and that's a perfectly acceptable solution in my book.Ridgway
Is there any solution?Biblical
Using the LostMouseCapture event instead works for me...Millicent
L
43

Here are the Blend behaviors implementing the answer solution for your convenience:

One for attaching to a single TextBox:

public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
    }

    private void AssociatedObjectGotKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void AssociatedObjectGotMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        AssociatedObject.SelectAll();   
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(!AssociatedObject.IsKeyboardFocusWithin)
        {
            AssociatedObject.Focus();
            e.Handled = true;
        }
    }
}

And one for attaching to the root of a container containing multiple TextBox'es:

public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture += HandleMouseCapture;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture -= HandleMouseCapture;
    }

    private static void HandleKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        var txt = e.NewFocus as TextBox;
        if (txt != null)
            txt.SelectAll();
    }

    private static void HandleMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var txt = e.OriginalSource as TextBox;
        if (txt != null)
            txt.SelectAll();
    }
}
Log answered 12/8, 2009 at 7:7 Comment(6)
This is by far the best and cleanest solution. Thanks a lot for sharing it.Bruton
It looks really nice, but for some reason it breaks tab control... Any idea why?Monarchism
I'd like to use yor solution. But really lost... maybe do you have a sample?Dulosis
When you click somewhere in the textbox while having focus (imagine you want to move caret to another place) it will SelectAll again instead of moving caret. It's unexpected. Fixed it by replacing GotMouseCapture with MouseDoubleClick which is common. Thanks to latter solutions from MSDN.Daren
It doesn't seem to work when the textbox receives initial focus via FocusManager.FocusedElement. Any ideas why?Nee
SelectAllTextOnFocusBehavior works perfect but SelectAllTextOnFocusMultiBehavior has the same issue as in the question. I tried to fix by adding the PreviewMouseLeftButtonDown but that isn't fired somehow... It's just selected correctly if you click behind the text and not in the textSchizont
S
34

I solved this problem using an Attached Behavior rather than an Expression Behavior as in Sergey's answer. This means I don't need a dependency on System.Windows.Interactivity in the Blend SDK:

public class TextBoxBehavior
{
    public static bool GetSelectAllTextOnFocus(TextBox textBox)
    {
        return (bool)textBox.GetValue(SelectAllTextOnFocusProperty);
    }

    public static void SetSelectAllTextOnFocus(TextBox textBox, bool value)
    {
        textBox.SetValue(SelectAllTextOnFocusProperty, value);
    }

    public static readonly DependencyProperty SelectAllTextOnFocusProperty =
        DependencyProperty.RegisterAttached(
            "SelectAllTextOnFocus",
            typeof (bool),
            typeof (TextBoxBehavior),
            new UIPropertyMetadata(false, OnSelectAllTextOnFocusChanged));

    private static void OnSelectAllTextOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var textBox = d as TextBox;
        if (textBox == null) return;

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

        if ((bool) e.NewValue)
        {
            textBox.GotFocus += SelectAll;
            textBox.PreviewMouseDown += IgnoreMouseButton;
        }
        else
        {
            textBox.GotFocus -= SelectAll;
            textBox.PreviewMouseDown -= IgnoreMouseButton;
        }
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox == null) return;
        textBox.SelectAll();
    }

    private static void IgnoreMouseButton(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        var textBox = sender as TextBox;
        if (textBox == null || (!textBox.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;

        e.Handled = true;
        textBox.Focus();
    }
}

You can then use it in your XAML like this:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

I blogged about it here.

Sculpt answered 25/7, 2013 at 13:19 Comment(4)
I like this approach but the Get/Set methods shouldn't end in "Property"; I had to remove that to get the code compiling after adding the Xaml portion.Gunner
Very nice, worked just as expected. I like this because it helps me keep View concerns separated when doing MVVM.Kendall
The blog post link didn't work for me, this did dutton.me.uk/2013-07-25/…Tacho
Thanks @Steve, I've updated the URI in the answerSculpt
G
17

Here's a very good very simple solution on MSDN:

<TextBox
    MouseDoubleClick="SelectAddress"
    GotKeyboardFocus="SelectAddress"
    PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />

Here's the code behind:

private void SelectAddress(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        tb.SelectAll();
    }
}

private void SelectivelyIgnoreMouseButton(object sender,
    MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}
Geller answered 2/5, 2013 at 0:19 Comment(2)
Essentially, this is the same solution as the most rated one in this thread. But since it two years earlier, now I know where from @Fidelfidela borrowed it ;)Log
This solution seemed the easiest and worked for me. I wanted a specific subset of text selected by default when entering the textbox.Interested
I
12

I think this works well:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
            {
                tb.SelectAll();
            }), System.Windows.Threading.DispatcherPriority.Input);
}

If you would like to implement it as an extension method:

public static void SelectAllText(this System.Windows.Controls.TextBox tb)
{
    tb.Dispatcher.BeginInvoke(
        new Action(delegate
        {
            tb.SelectAll();
        }), System.Windows.Threading.DispatcherPriority.Input);
}

And in your GotFocus event:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (TextBox)e.OriginalSource;
    tb.SelectAllText();
}

I discovered the solution above because several months ago I was looking for a way to set focus to a given UIElement. I discovered the the code below somewhere (credit is hereby given) and it works well. I post it even though it is not directly related to the OP's question because it demonstrates the same pattern of using Dispatcher to work with a UIElement.

// Sets focus to uiElement
public static void DelayedFocus(this UIElement uiElement)
{
    uiElement.Dispatcher.BeginInvoke(
    new Action(delegate
    {
        uiElement.Focusable = true;
        uiElement.Focus();
        Keyboard.Focus(uiElement);
    }),
    DispatcherPriority.Render);
}
Incidence answered 24/2, 2012 at 17:46 Comment(2)
I guess this is the simplest method to implement. after creating the extension method you will just have to call myTextBox.SelectAllText() . Why is this answer not received more points? why are the other solutions so much better?Smithsonite
I would avoid this method because it's relying on an async call to run after the textbox's MouseUp handler. I wouldn't trust this to be 100% deterministic, and may lead to inconsistent behavior. Even though it may be unlikely to occur, I would rather go with the surefire methods above.Septum
V
7

In App.xaml file:

<Application.Resources>
    <Style TargetType="TextBox">
        <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
    </Style>
</Application.Resources>

In App.xaml.cs file:

private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
{
    ((TextBox)sender).SelectAll();
}

With this code you reach all TextBox in your application.

Viewer answered 13/7, 2015 at 10:17 Comment(0)
S
6

I've found none of the answers presented here mimic a standard Windows textbox. For instance, try to click in the white space between the last character of the textbox and the right side of the textbox. Most of the solutions here will always select the whole content, which makes it very difficult to append text to a textbox.

The answer that I present here behaves better in this respect. It is a behavior (so it requires the System.Windows.Interactivity assembly from the Blend SDK). It could be rewritten using attached properties as well.

public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
    }

    void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Find the textbox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        var textBox = parent as TextBox;
        Debug.Assert(textBox != null);

        if (textBox.IsFocused) return;

        textBox.SelectAll();
        Keyboard.Focus(textBox);
        e.Handled = true;
    }
}

This is based on code I've found here.

Scipio answered 27/7, 2010 at 13:29 Comment(3)
While this is a good answer, I think that when user clicks on the white space his intention (in a business application) is most probably to override the entire value, so selecting all is the right approach.Log
Sergey: the first click will select the entire value, the second click will put the cursor at the right of the value. In the other presented solutions, the second click will keep the entire value selected, making it very difficult to append to the value.Scipio
How is this used? I added this code to App.xaml.cs but it didn't seem to have an effect on the TextBoxes in my app.Piscator
L
6

This simple implementation works perfectly for me:

void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    ((TextBox) sender).SelectAll();
}

void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var TextBox = (TextBox) sender;
    if (!TextBox.IsKeyboardFocusWithin)
    {
        TextBox.Focus();
        e.Handled = true;
    }
}

To apply it to all TextBox's, put the following code after InitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));
Larcenous answered 20/10, 2013 at 23:55 Comment(0)
K
5

I have used Nils' answer but converted to more flexible.

public enum SelectAllMode
{

    /// <summary>
    ///  On first focus, it selects all then leave off textbox and doesn't check again
    /// </summary>
    OnFirstFocusThenLeaveOff = 0,

    /// <summary>
    ///  On first focus, it selects all then never selects
    /// </summary>
    OnFirstFocusThenNever = 1,

    /// <summary>
    /// Selects all on every focus
    /// </summary>
    OnEveryFocus = 2,

    /// <summary>
    /// Never selects text (WPF's default attitude)
    /// </summary>
    Never = 4,
}

public partial class TextBox : DependencyObject
{
    public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
        "SelectAllMode",
        typeof(SelectAllMode?),
        typeof(TextBox),
        new PropertyMetadata(SelectAllModePropertyChanged));

    private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is System.Windows.Controls.TextBox)
        {
            var textBox = d as System.Windows.Controls.TextBox;

            if (e.NewValue != null)
            {
                textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            }
            else
            {
                textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;
                textBox.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
            }
        }
    }

    private static void OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        DependencyObject dependencyObject = GetParentFromVisualTree(e.OriginalSource);

        if (dependencyObject == null)
            return;

        var textBox = (System.Windows.Controls.TextBox)dependencyObject;
        if (!textBox.IsKeyboardFocusWithin)
        {
            textBox.Focus();
            e.Handled = true;
        }
    }

    private static DependencyObject GetParentFromVisualTree(object source)
    {
        DependencyObject parent = source as UIElement;
        while (parent != null && !(parent is System.Windows.Controls.TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
        if (textBox == null) return;

        var selectAllMode = GetSelectAllMode(textBox);

        if (selectAllMode == SelectAllMode.Never)
        {
            textBox.SelectionStart = 0;
            textBox.SelectionLength = 0;
        }
        else
            textBox.SelectAll();

        if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
            SetSelectAllMode(textBox, SelectAllMode.Never);
        else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
            SetSelectAllMode(textBox, null);
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
    public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
    {
        return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
    }

    public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
    {
        @object.SetValue(SelectAllModeProperty, value);
    }
}

In XAML, you can use like one of these:

<!-- On first focus, it selects all then leave off textbox and doesn't check again -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />

<!-- On first focus, it selects all then never selects -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />

<!-- Selects all on every focus -->
<TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />

<!-- Never selects text (WPF's default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />
Karlik answered 17/2, 2017 at 2:32 Comment(1)
Really good solution for use in templates since you can bind it to xaml without any actual codebehind, just extended behaviour of the textbox.Sivia
V
4

I have a slightly simplified answer for this (with just the PreviewMouseLeftButtonDown event) which seems to mimic the usual functionality of a browser:

In XAML you have a TextBox say:

<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                 PreviewMouseLeftButtonDown="SelectAll" />

In codebehind:

private void SelectAll(object sender, MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);

    if (tb == null)
    {
        return;
    }

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.SelectAll();
        e.Handled = true;
        tb.Focus();
    }
}
Vizard answered 29/11, 2011 at 9:46 Comment(1)
Might want to add a GotKeyboardFocus event with TextBox.SelectAll() inside for people who tab their way around your application. Your solution works for PasswordBoxes too (since PasswordBoxes are sealed types they cannot be extended).Eelworm
Z
4

Taken from here:

Register global event handler in App.xaml.cs file:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
    new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Then the handler is as simple as:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}
Zakaria answered 12/12, 2014 at 20:11 Comment(1)
This way it also affects multi-line text fields, which should come as quite a surprise to Windows-experienced users.Reactance
U
3

I realize this is very old, but here is my solution which is based on the expressions/microsoft interactivity and interactions name spaces.

First, I followed the instructions at this link to place interactivity triggers into a style.

Then it comes down to this

<Style x:Key="baseTextBox" TargetType="TextBox">
  <Setter Property="gint:InteractivityItems.Template">
    <Setter.Value>
      <gint:InteractivityTemplate>
        <gint:InteractivityItems>
          <gint:InteractivityItems.Triggers>
            <i:EventTrigger EventName="GotKeyboardFocus">
              <ei:CallMethodAction MethodName="SelectAll"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
              <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                TargetObject="{Binding ElementName=HostElementName}"/>
            </i:EventTrigger>
          </gint:InteractivityItems.Triggers>
        </gint:InteractivityItems>
      </gint:InteractivityTemplate>
    </Setter.Value>
  </Setter>
</Style>

and this

public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  TextBox tb = e.Source as TextBox;
  if((tb != null) && (tb.IsKeyboardFocusWithin == false))
  {
    tb.Focus();
    e.Handled = true;
  }
}

In my case, I have a user control where the text boxes are that has a code-behind. The code-behind has the handler function. I gave my user control a name in XAML, and I am using that name for the element. This is working perfectly for me. Simply apply the style to any TextBox where you would like to have all the text selected when you click in the TextBox.

The first CallMethodAction calls the text box's SelectAll method when the GotKeyboardFocus event on the TextBox fires.

I hope this helps.

Urine answered 26/3, 2018 at 21:27 Comment(3)
Since this is such an old questions, it might help your answer get some attention if you mention why someone might choose this approach.Sorrento
First off, this does not need to be put in a style, but I think it obvious that there are many text box controls that need this, a style is the way to go.Urine
Maybe some will not agree with this approach, however, as to why you might use this approach, it does not require subclassing TextBox, registering class handler events, extension methods, creating attached properties, etc. As a style, it could also be added to the resource dictionary of any xaml project. Without the x:Key, it would be applied to any TextBox instance within the scope of the resource dictionary without having to alter the xaml of each individual text box. In some cases, it may be a cleaner approach.Urine
K
3

Here is an attempt to solve some of the problems with other solutions:

  1. Using right click context menu for cut/copy/past selects all text even if you didn't select it all.
  2. When returning from right click context menu, all text is always selected.
  3. When returning to the application with Alt+Tab, all text is always selected.
  4. When trying to select only part of the text on the first click, all is always selected (unlike Google chromes address bar for example).

The code I wrote is configurable. You can choose on what actions the select all behavior should occur by setting three readonly fields: SelectOnKeybourdFocus, SelectOnMouseLeftClick, SelectOnMouseRightClick.

The downside of this solution is that it's more complex and static state is stored. Its seems like an ugly struggle with the defaults behavior of the TextBox control. Still, it works and all the code is hidden in the Attached Property container class.

public static class TextBoxExtensions
{
    // Configuration fields to choose on what actions the select all behavior should occur.
    static readonly bool SelectOnKeybourdFocus = true;
    static readonly bool SelectOnMouseLeftClick = true;
    static readonly bool SelectOnMouseRightClick = true;

    // Remembers a right click context menu that is opened 
    static ContextMenu ContextMenu = null;

    // Remembers if the first action on the TextBox is mouse down 
    static bool FirstActionIsMouseDown = false;

    public static readonly DependencyProperty SelectOnFocusProperty =
        DependencyProperty.RegisterAttached("SelectOnFocus", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChanged)));

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetSelectOnFocus(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnFocusProperty);
    }

    public static void SetSelectOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnFocusProperty, value);
    }

    private static void OnSelectOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox)) return;

        if (GetSelectOnFocus(textBox))
        {
            // Register events
            textBox.PreviewMouseDown += TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp += TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus += TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus += TextBox_LostKeyboardFocus;
        }
        else
        {
            // Unregister events
            textBox.PreviewMouseDown -= TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp -= TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus -= TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus -= TextBox_LostKeyboardFocus;
        }
    }

    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // If mouse clicked and focus was not in text box, remember this is the first click.
        // This will enable to prevent select all when the text box gets the keyboard focus 
        // right after the mouse down event.
        if (!textBox.IsKeyboardFocusWithin)
        {
            FirstActionIsMouseDown = true;
        }
    }

    private static void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnMouseLeftClick/SelectOnMouseRightClick is true and left/right button was clicked
        // 3) This is the first click
        // 4) No text is selected
        if (((SelectOnMouseLeftClick && e.ChangedButton == MouseButton.Left) || 
            (SelectOnMouseRightClick && e.ChangedButton == MouseButton.Right)) &&
            FirstActionIsMouseDown &&
            string.IsNullOrEmpty(textBox.SelectedText))
        {
            textBox.SelectAll();
        }

        // It is not the first click 
        FirstActionIsMouseDown = false;
    }

    private static void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnKeybourdFocus is true
        // 2) Focus was not previously out of the application (e.OldFocus != null)
        // 3) The mouse was pressed down for the first after on the text box
        // 4) Focus was not previously in the context menu
        if (SelectOnKeybourdFocus &&
            e.OldFocus != null &&
            !FirstActionIsMouseDown &&
            !IsObjectInObjectTree(e.OldFocus as DependencyObject, ContextMenu))
        {
            textBox.SelectAll();
        }

        // Forget ContextMenu
        ContextMenu = null;
    }

    private static void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Remember ContextMenu (if opened)
        ContextMenu = e.NewFocus as ContextMenu;

        // Forget selection when focus is lost if:
        // 1) Focus is still in the application
        // 2) The context menu was not opened
        if (e.NewFocus != null
            && ContextMenu == null)
        {
            textBox.SelectionLength = 0;
        }
    }

    // Helper function to look if a DependencyObject is contained in the visual tree of another object
    private static bool IsObjectInObjectTree(DependencyObject searchInObject, DependencyObject compireToObject)
    {
        while (searchInObject != null && searchInObject != compireToObject)
        {
            searchInObject = VisualTreeHelper.GetParent(searchInObject);
        }

        return searchInObject != null;
    }
}

To attache the Attached Property to a TextBox, all you need to do is add the xml namespace (xmlns) of the Attached Property and then use it like this:

<TextBox attachedprop:TextBoxExtensions.SelectOnFocus="True"/>

Some notes about this solution:

  1. To override the default behavior of a mouse down event and enable selecting only part of the text on the first click, all text is selected on mouse up event.
  2. I had to deal with the fact the the TextBox remembers its selection after it loses focus. I actually have overridden this behavior.
  3. I had to remember if a mouse button down is the first action on the TextBox (FirstActionIsMouseDown static field).
  4. I had to remember the context menu opened by a right click (ContextMenu static field).

The only side effect I found is when SelectOnMouseRightClick is true. Sometimes the right-click context menu flickers when its opened and right-clicking on a blank are in the TextBox does not do "select all".

Krutz answered 12/5, 2020 at 16:47 Comment(0)
D
2

After googling and testing, I've found a simple solution that worked for me.

You need to add an event handler to the Loaded event of your container window:

private void yourwindow_Loaded(object sender, RoutedEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.PreviewMouseLeftButtonDownEvent,
        new RoutedEventHandler(SelectivelyIgnoreMouseButton));
}

Next, you have to create the handler to the referenced RoutedEventHandler in previous code:

private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}

Now, you can add the SelectAll() command on GotFocus event handlers to any TextBox controls separately:

private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Your text now is selected on focus!

Adapted from Dr. WPF solution, MSDN Forums

Disciplinant answered 2/6, 2017 at 0:30 Comment(1)
I just used: private async void TBTime_GotFocus(object sender, RoutedEventArgs e) { TextBox tb = (TextBox)e.OriginalSource; await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, async () => { tb.SelectAll(); }); }Shanelleshaner
E
2

This is by far the most straightforward solution I found.

You are going to need only a few lines of code.

Add a global handler to the application (App.xaml.cs). Use the EventManager class to register a global event handler against a type, in this case, the TextBox.

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Then use the event handler to select all the Textbox contents.

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Check here: WPF TextBox SelectAll on Focus

I hope it helps.

Elapse answered 12/9, 2017 at 5:13 Comment(1)
The automatic selection also affects multi-line text fields, which should come as quite a surprise to Windows-experienced users. But a good starting point.Reactance
U
2

Here is the C# version of the answer posted by @Nasenbaer

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

whereas MyTextBox_GotFocus is the event handler assigned to the GotFocus event of MyTextBox.

Ultra answered 22/1, 2018 at 15:48 Comment(0)
P
1

For those interested in Donnelle's/Groky's approach, but want a click to the right of the last character (but still within the TextBox) to place the caret at the end of the entered text, I've come up with this solution:

int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
{
    int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);

    // Check if the clicked point is actually closer to the next character
    // or if it exceeds the righmost character in the textbox
    // (in this case return increase the position by 1)
    Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
    Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
    double charWidth = charRightEdge.X - charLeftEdge.X;
    if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;

    return position;
}

void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
{
    // Find the TextBox
    DependencyObject parent = e.OriginalSource as UIElement;
    while (parent != null && !(parent is TextBox))
        parent = VisualTreeHelper.GetParent(parent);

    if (parent != null)
    {
        var textBox = (TextBox)parent;
        if (!textBox.IsKeyboardFocusWithin)
        {
            // If the text box is not yet focused, give it the focus and
            // stop further processing of this click event.
            textBox.Focus();
            e.Handled = true;
        }
        else
        {
            int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
            textBox.CaretIndex = pos;
        }
    }
}

void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

The GetRoundedCharacterIndexFromPoint method was taken from this post.

Piscator answered 21/12, 2011 at 21:55 Comment(2)
Works fine, but the double click event doesn't get triggeredGran
Actually it does enter to the doubleclick event but the OriginalSource property is of type TextBoxView. So the SelectAllText method should be like this: private static void SelectAllText(object sender, RoutedEventArgs e) { var textBox = e.OriginalSource as TextBox; if (textBox != null) { textBox.SelectAll(); System.Diagnostics.Debug.WriteLine(" Selected ALL "); } else if (sender is TextBox) { (sender as TextBox).SelectAll(); }Gran
L
1
#region TextBoxIDCard selection
private bool textBoxIDCardGotFocus = false;
private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
{
    this.TextBoxIDCard.SelectAll();
}

private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
{
    textBoxIDCardGotFocus = false;
}

private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (textBoxIDCardGotFocus == false)
    {
        e.Handled = true;
        this.TextBoxIDCard.Focus();
        textBoxIDCardGotFocus = true;
    }
} 
#endregion
Linkman answered 28/1, 2012 at 17:11 Comment(1)
If you have 20 textboxes on a window, will you create 3 methods for every textbox ? This approach is not good. Take a look here: rachel53461.wordpress.com/2011/11/05/…Packet
T
1

Try this extension method to add the desired behaviour to any TextBox control. I havn't tested it extensively yet, but it seems to fulfil my needs.

public static class TextBoxExtensions
{
    public static void SetupSelectAllOnGotFocus(this TextBox source)
    {
        source.GotFocus += SelectAll;
        source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

    private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            if (!textBox.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                textBox.Focus();
            }
        }
    }
}
Termagant answered 14/3, 2012 at 0:23 Comment(0)
S
1

I had same problem. In VB.Net it works easy that way:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

Codehind:

Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
    Me.Dispatcher.BeginInvoke(Sub()
                                  txtFilterText.SelectAll()
                              End Sub, DispatcherPriority.ApplicationIdle, Nothing)
End Sub

C# (thanks to ViRuSTriNiTy)

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}
Shire answered 23/4, 2013 at 20:10 Comment(3)
Best solution for me, i've posted a C# translation here: https://mcmap.net/q/108718/-how-to-automatically-select-all-text-on-focus-in-wpf-textboxUltra
For me, this approach occasionally fails to select text. I think it's race condition due to BeginInvoke.Telesthesia
Please specify. The dispatcher priority is working on default applications as expected. What is your situation? Did you try exact as described? Anything special in your solution?Shire
G
1

I searched a lot for the solution, I found couple of solutions to selectall But, the issue is when we do right click and do cut/copy after selecting part of text from text box, it selects all even I selected part of text. To fix this here is the solution. Just add the below code in the keyboard select event. This worked for me.

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is TextBox)
    {
        TextBox textBox = d as TextBox;
        if ((e.NewValue as bool?).GetValueOrDefault(false))
        {
            textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;                 
        }
        else
        {
            textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;

        }
    }
}


private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}
Godless answered 23/1, 2017 at 19:38 Comment(0)
C
1

i use this code

  private void txtNav_GotFocus(object sender, RoutedEventArgs e)
            {
                e.Handled = true;
                var c = new DispatcherTimer();
                c.Interval = TimeSpan.FromMilliseconds(100);
                c.Tick += (a1, a2) =>
                {
                    c.IsEnabled = false;
                    txtNav.SelectAll();
                };
                c.IsEnabled = true;
    
            }
Carvalho answered 9/3, 2021 at 22:41 Comment(0)
I
0

I have tested all of them but only the following worked out:

protected override void OnStartup(StartupEventArgs e) 
{
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
   new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(SelectAllText), true);
    EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
      new RoutedEventHandler(GotFocus), true);          
}

private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
{
    var textbox = (sender as TextBox);
    if (textbox != null)
    {
        int hc = textbox.GetHashCode();
        if (hc == LastHashCode)
        {
            if (e.OriginalSource.GetType().Name == "TextBoxView")
            {
                e.Handled = true;
                textbox.Focus();
                LastHashCode = -1;
            }
        }
    }
    if (textbox != null) textbox.Focus();
}

private static void SelectAllText(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        textBox.SelectAll();
}

private static int LastHashCode;
private static void GotFocus(object sender, RoutedEventArgs e)
{
    var textBox = e.OriginalSource as TextBox;
    if (textBox != null)
        LastHashCode = textBox.GetHashCode();
}
Isobath answered 28/7, 2010 at 9:41 Comment(2)
That's also an obscene misuse of hash codes. I'd read this, linkRecognizor
And using GetType().Name instead of is or as is pretty hackyRecognizor
M
0

This seems to work well for me. It's basically a recap of some earlier posts. I just put this into my MainWindow.xaml.cs file in the constructor. I create two handlers, one for keyboard, and one for the mouse, and funnel both events into the same function, HandleGotFocusEvent, which is defined right after the constructor in the same file.

public MainWindow()
{
   InitializeComponent();

   EventManager.RegisterClassHandler(typeof(TextBox), 
      UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);
   EventManager.RegisterClassHandler(typeof(TextBox),
      UIElement.GotMouseCaptureEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);   
}
private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
{
   if (sender is TextBox)
      (sender as TextBox).SelectAll();
}
Madi answered 27/4, 2011 at 23:15 Comment(1)
Nice and easy, but seems to have a timing problem - every other try (mouse click), it de-selects again immediately...?Lusatia
J
0

An easy way to override the mouseDown and select all after doubleclick is:

public class DoubleClickTextBox: TextBox
{

    public override void EndInit()
    {
        base.EndInit();            
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        this.Cursor = Cursors.Arrow;
    }
    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {

    }

    protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        this.SelectAll();
    }
}
Jotham answered 29/11, 2012 at 11:14 Comment(0)
U
0

Try putting this in the constructor of whatever control is housing your textbox:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}
Underwear answered 30/1, 2015 at 19:57 Comment(1)
This approach doesn't not work when you put this in a window constructor.Ultra
A
0

If there's an event that deselects text during the OnFocus mouse up, I usually just delay the select all.

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (TextBox.Text != null)
    {
        _ = Task.Run(() =>
        {
            Dispatcher.Invoke(
                async () => {
                    await Task.Delay(100);
                    TextBox.SelectAll();
                }
            );
        });
    }
}
Avalos answered 2/3, 2020 at 2:12 Comment(0)
N
0

The simplist and perfect solution, is to use a timer to select all text 20ms after textbox got focus:

Dim WithEvents Timer As New DispatcherTimer()

Set the interval: Timer.Interval = TimeSpan.FromMilliseconds(20)

respond to events (I am inheriting the TextBox control here, so I am overriding its events:

Protected Overrides Sub OnGotFocus(e As RoutedEventArgs)
        Timer.Start()
        MyBase.OnGotFocus(e)
    End Sub


    Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
        Timer.Stop()
        Me.SelectAll()
    End Sub

And that is all!

Narcissus answered 14/9, 2020 at 0:27 Comment(0)
B
0

This seemed to work for me...

private bool TextBoxFocusBool;

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    TextBoxFocusBool = true;
}

private void TextBox_LostMouseCapture(object sender, MouseEventArgs e)
{
    if (TextBox.SelectionLength == 0 & TextBoxFocusBool == true)
    {
        TextBox.SelectAll();
        TextBoxFocusBool = false;
    }
}

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    TextBoxFocusBool = true;
}
Bigotry answered 4/9, 2022 at 4:16 Comment(0)
E
0

I thought this was a lot easier.

nameOfTextbox.Focus();
nameOfTextbox.Select(0, nameOfTextbox.Text.Length);

Also if someone else had the problem of your cursor not focusing on the textbox you can use this in place of nameOfTextbox.Focus(); above.

Dispatcher.BeginInvoke(DispatcherPriority.Input,
new Action(delegate () {
    nameOfTextbox.Focus();         // Set Logical Focus
    Keyboard.Focus(nameOfTextbox); // Set Keyboard Focus
}));
Emigrant answered 12/12, 2022 at 17:5 Comment(0)
A
-1

WOW! After reading all the above I find myself overwhelmed and confused. I took what I thought I learned in this post and tried something completely different. To select the text in a TexTbox when it gets focus I use this:

private void TextField_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as Textbox);
    if(tb != null)
    {
        e.Handled = true;
        tb.Focus();
        tb.SelectAll();
    }
}

Set the GotFocus property of the TexTbox to this method.

Running the application and clicking once in the TexTbox highlights everything already in the TexTbox.

If indeed, the objective is to select the text when the user clicks in the TexTbox, this seems simple and involves a whole lot less code. Just saying...

Arianearianie answered 30/12, 2014 at 19:44 Comment(1)
But when you let go of the mouse it unselects the text. So this doesn't solve the problem.Hierarch
D
-1

For me this is working excellent after a click with the mouse on the TextBox:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    Dispatcher.BeginInvoke(() => ((TextBox)sender).SelectAll());
    e.Handled = true;
}
Diluent answered 25/12, 2021 at 21:0 Comment(1)
This is a duplicate answer. See https://mcmap.net/q/108718/-how-to-automatically-select-all-text-on-focus-in-wpf-textboxCoben

© 2022 - 2024 — McMap. All rights reserved.