Why is focus in WPF so tricky? [managing and understanding focus in a WPF application]
The Basic Idea
Let’s digress first to the Win32 world. In these apps, it’s pretty trivial to do this: handle theWM_GOTFOCUS message, and call ::SendMessage(hWnd, EM_SETSEL, 0, -1).
In Windows Forms, it’s equally simple: handle the control’s GotFocus event and calltextBox.SelectAll().
In WPF, you would think you would just handle the GotFocus event and calltextBox.SelectAll() as well and be done. This will sort of work, but it’s not acceptable.
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();
}
}