How to select all WPF TextBox text on focus using an Attached Behavior
UPDATE 12/11/2013: Fixed a mistake in the example code; the setter and getter shouldn't have "Property" in the name.
I have a simple requirement to select all of the text in a WPF TextBox when it receives focus, this lets a user tab through a bunch of TextBoxes and edit the values directly without having to use the mouse.
Although there are a few methods I could use, I thought I'd tackle this using the "Ramora", or "Attached Behavior" pattern. I always forget the syntax, hence this post.
Implementing an Attached Behavior involves creating a boolean Attached Property to indicate whether the behavior is to be applied, and then implementing the behavior in the property's change handler, like this:
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.IsKeyboardFocusWithin) return; e.Handled = true; textBox.Focus(); } }
Which means you can use it like this in XAML:
<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>
So as you can see, it's really quite simple. I hook into the GotFocus event in `OnSelectAllTextOnFocusChanged`, and call `SelectAll` where I select all of the TextBox's text.
I added a further event handler to ensure that mouse clicks within the TextBox didn't highlight the text when it already had focus but this isn't essential.