This is rather old, but I'll display my answer anyway.
I have chosen part of Donelles answer (skip'ed the double-click) for I think this creates the least astonishment in the users. However, like gcores I dislike the need to create a derives class. But I also don't like gcores "on Startup..." method. And I need this on a "generally but not always"-basis.
I have Implemented this as an attached dependency Property so I can set SelectTextOnFocus.Active=True
in xaml. I find this way the most pleasing.
namespace foo.styles.behaviour
{
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 Property to True in a (global) TextBox-Style. This way "selecting the Text" is always "on", but I am able to disable it on a per-Textbox-basis.