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.