If you take a close look at the TextBox element, you will notice that the first click on it results in the following: the element gets the focus and the caret carriage stands in place of the user's click.
When we are trying on a focus event to simply select all the text inside:
... text = new TextBox(); text.Text = "Sample text"; text.GotFocus += text_GotFocus; ... ... private void text_GotFocus(object sender, RoutedEventArgs e) { TextBox text = sender as TextBox; if(text != null) text.SelectAll(); } ...
The following happens. Our text element receives the event (Preview) MouseLeftButtonDown, which causes the focus and only then sets the caret in the desired position, thereby removing our selection from the focus event. This is the reason why when an element receives focus from the keyboard, the selection works fine, but when clicked there is none.
One solution is to catch the mouse event itself and process it, but the TextBox element has no mouse events other than (preview) DoubleMouseClick. In order to solve this problem, registration of an event for all TextBox elements via EventManager.RegisterClassHandler . At the same time, the event stops and the focus event is passed to the element.
... EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(StopTextBoxClick), true); ... ... private void StopTextBoxClick(object sender, MouseButtonEventArgs e) { TextBox text = sender as TextBox; if(text != null){ e.Handled = true; text.Focus(); } } ...
In this embodiment, there is one problem, now every time the focus event is triggered and the text always remains selected, and the mouse does not work. The last edit is to stop the event only when the element has not yet received focus. You can use the IsFocused property to do this, but since the element may contain some other nested elements, IsKeyboardFocusWithin used.
By the way, the event of receiving the focus can be set not through text.GotFocus += text_GotFocus , but through the same EventManager.RegisterClassHandler . There will be no difference in this case. Here we come to this code:
... text = new TextBox(); text.Text = "Sample text"; ... ... EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent, new MouseButtonEventHandler(StopTextBoxClick), true); EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent, new RoutedEventHandler(text_GotFocus), true); ... ... private void text_GotFocus(object sender, RoutedEventArgs e) { TextBox text = sender as TextBox; if(text != null) text.SelectAll(); } private void StopTextBoxClick(object sender, MouseButtonEventArgs e) { TextBox text = sender as TextBox; if (text != null && !text.IsKeyboardFocusWithin) { e.Handled = true; text.Focus(); } } ...
And all due to the fact that the click event works this way - it sets the focus itself and then sets the carriage, removing our attempts at selection.
PS Again, the event affects all TextBox elements, so if you do not need it, you need to somehow restrict the events in the code. To do this, inside the if (text != null && !text.IsKeyboardFocusWithin) check if (text != null && !text.IsKeyboardFocusWithin) you can already check additional conditions and properties.