Как автоматически выбрать весь текст в фокусе в WPF TextBox?

Если я вызываю SelectAll из обработчика события GotFocus, он не работает с мышью - выбор исчезает, как только мышь отпускается.

РЕДАКТИРОВАТЬ: Людям нравится ответ Доннеле, я постараюсь объяснить, почему мне это не понравилось, как принятый ответ.

  • Это сложнее, в то время как принятый ответ делает то же самое более простым способом.
  • Удобство принятого ответа лучше. Когда вы нажимаете посередине текста, текст становится недоступным при отпускании мыши, что позволяет сразу начать редактирование, и если вы все еще хотите выбрать все, просто нажмите кнопку еще раз, и на этот раз он не отменит выбор при отпускании. Следуя рецепту Донеллы, если я щелкнул по середине текста, я должен щелкнуть второй раз, чтобы иметь возможность редактировать. Если я щелкнул где-нибудь в тексте и вне текста, это, скорее всего, означает, что я хочу начать редактирование, а не переписывать все.

Ответ 1

Не знаю, почему он теряет выделение в событии GotFocus.

Но одно решение - сделать выбор в событиях GotKeyboardFocus и GotMouseCapture. Таким образом, он всегда будет работать.

Ответ 2

У нас это так, что первый щелчок выбирает все, а другой клик идет на курсор (наше приложение предназначено для использования на планшетах с ручками).

Вы можете найти это полезным.

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();
    }
}

Ответ 3

Ответ Donnelle работает лучше всего, но для того, чтобы получить новый класс для использования, это боль.

Вместо этого я регистрирую обработчики обработчиков в App.xaml.cs для всех текстовых полей в приложении. Это позволяет мне использовать ответ Donnelle со стандартным элементом управления TextBox.

Добавьте в свой App.xaml.cs следующие методы:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e) 
    {
        // Select the text in a TextBox when it receives focus.
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseLeftButtonDownEvent,
            new MouseButtonEventHandler(SelectivelyIgnoreMouseButton));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotKeyboardFocusEvent, 
            new RoutedEventHandler(SelectAllText));
        EventManager.RegisterClassHandler(typeof(TextBox), TextBox.MouseDoubleClickEvent,
            new RoutedEventHandler(SelectAllText));
        base.OnStartup(e); 
    }

    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 focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }
}

Ответ 4

Это довольно старый, но я все равно покажу свой ответ.
Я выбрал часть ответа Donnelle (пропустил двойной щелчок), поскольку я думаю, что это создает наименьшее удивление у пользователей. Однако, как и gcores, мне не нравится необходимость создания производного класса. Но мне также не нравится gcores "on Startup...". И мне это нужно на "вообще, но не всегда".

Я реализовал это как свойство зависимой зависимости, поэтому я могу установить SelectTextOnFocus.Active=True в xaml. Я нахожу этот путь самым приятным.

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);
        }
    }
}

Для моего "общего, но не всегда" -feature я установил это свойство в True в (глобальном) TextBox-Style. Таким образом, "выбор текста" всегда "on", но я могу отключить его для каждого текстового поля.

Ответ 5

Ниже приведены действия Blend, реализующие решение для вашего решения:

Один для прикрепления к одному текстовому блоку:

public class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture += AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObjectPreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= AssociatedObjectGotKeyboardFocus;
        AssociatedObject.GotMouseCapture -= AssociatedObjectGotMouseCapture;
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObjectPreviewMouseLeftButtonDown;
    }

    private void AssociatedObjectGotKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        AssociatedObject.SelectAll();
    }

    private void AssociatedObjectGotMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        AssociatedObject.SelectAll();   
    }

    private void AssociatedObjectPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if(!AssociatedObject.IsKeyboardFocusWithin)
        {
            AssociatedObject.Focus();
            e.Handled = true;
        }
    }
}

И один для прикрепления к корню контейнера, содержащего несколько TextBox'ов:

public class SelectAllTextOnFocusMultiBehavior : Behavior<UIElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.GotKeyboardFocus += HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture += HandleMouseCapture;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.GotKeyboardFocus -= HandleKeyboardFocus;
        AssociatedObject.GotMouseCapture -= HandleMouseCapture;
    }

    private static void HandleKeyboardFocus(object sender,
        System.Windows.Input.KeyboardFocusChangedEventArgs e)
    {
        var txt = e.NewFocus as TextBox;
        if (txt != null)
            txt.SelectAll();
    }

    private static void HandleMouseCapture(object sender,
        System.Windows.Input.MouseEventArgs e)
    {
        var txt = e.OriginalSource as TextBox;
        if (txt != null)
            txt.SelectAll();
    }
}

Ответ 6

Здесь очень хорошее очень простое решение на MSDN:

<TextBox
    MouseDoubleClick="SelectAddress"
    GotKeyboardFocus="SelectAddress"
    PreviewMouseLeftButtonDown="SelectivelyIgnoreMouseButton" />

Вот код позади:

private void SelectAddress(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        tb.SelectAll();
    }
}

private void SelectivelyIgnoreMouseButton(object sender,
    MouseButtonEventArgs e)
{
    TextBox tb = (sender as TextBox);
    if (tb != null)
    {
        if (!tb.IsKeyboardFocusWithin)
        {
            e.Handled = true;
            tb.Focus();
        }
    }
}

Ответ 7

Хотя это старый вопрос, я только что столкнулся с этой проблемой, но решил ее, используя Attached Behavior, а не Expression Behavior, как в ответе Sergey. Это означает, что мне не нужна зависимость от System.Windows.Interactivity в Blend SDK:

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.IsReadOnly && textBox.IsKeyboardFocusWithin)) return;

        e.Handled = true;
        textBox.Focus();
    }
}

Затем вы можете использовать его в своем XAML следующим образом:

<TextBox Text="Some Text" behaviors:TextBoxBehavior.SelectAllTextOnFocus="True"/>

Я написал об этом здесь.

Ответ 8

Я думаю, что это хорошо работает:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = (TextBox)e.OriginalSource;
        tb.Dispatcher.BeginInvoke(
            new Action(delegate
                {
                    tb.SelectAll();
                }), System.Windows.Threading.DispatcherPriority.Input);
    }

Если вы хотите реализовать его как метод расширения:

public static void SelectAllText(this System.Windows.Controls.TextBox tb)
    {
        tb.Dispatcher.BeginInvoke(
            new Action(delegate
            {
                tb.SelectAll();
            }), System.Windows.Threading.DispatcherPriority.Input);
    }

И в вашем событии GotFocus:

private void ValueText_GotFocus(object sender, RoutedEventArgs e)
    {
        TextBox tb = (TextBox)e.OriginalSource;
        tb.SelectAllText();
    }

Я нашел решение выше, потому что несколько месяцев назад я искал способ сосредоточиться на данном UIElement. Я где-то обнаружил код ниже (здесь дан кредит), и он работает хорошо. Я публикую его, даже если он напрямую не связан с вопросом OP, поскольку он демонстрирует ту же схему использования Диспетчера для работы с UIElement.

// Sets focus to uiElement
    public static void DelayedFocus(this UIElement uiElement)
    {
        uiElement.Dispatcher.BeginInvoke(
        new Action(delegate
        {
            uiElement.Focusable = true;
            uiElement.Focus();
            Keyboard.Focus(uiElement);
        }),
        DispatcherPriority.Render);
    }

Ответ 9

Я не нашел ни одного из представленных здесь ответов, имитирующих стандартное текстовое поле Windows. Например, попробуйте щелкнуть пробел между последним символом текстового поля и правой стороной текстового поля. Большинство решений здесь всегда будут выбирать весь контент, что затрудняет добавление текста в текстовое поле.

Ответ, который я здесь представляю, ведет себя лучше в этом отношении. Это поведение (для этого требуется сборка System.Windows.Interactivity из Blend SDK). Он также может быть переписан с использованием добавленных свойств.

public sealed class SelectAllTextOnFocusBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewMouseLeftButtonDown += AssociatedObject_PreviewMouseLeftButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewMouseLeftButtonDown -= AssociatedObject_PreviewMouseLeftButtonDown;
    }

    void AssociatedObject_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // Find the textbox
        DependencyObject parent = e.OriginalSource as UIElement;
        while (parent != null && !(parent is TextBox))
            parent = VisualTreeHelper.GetParent(parent);

        var textBox = parent as TextBox;
        Debug.Assert(textBox != null);

        if (textBox.IsFocused) return;

        textBox.SelectAll();
        Keyboard.Focus(textBox);
        e.Handled = true;
    }
}

Это основано на коде, который я нашел здесь.

Ответ 10

Эта простая реализация отлично работает для меня:

void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    ((TextBox) sender).SelectAll();
}

void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var TextBox = (TextBox) sender;
    if (!TextBox.IsKeyboardFocusWithin)
    {
        TextBox.Focus();
        e.Handled = true;
    }
}

Чтобы применить его ко всем TextBox ', введите следующий код после InitializeComponent();

EventManager.RegisterClassHandler(typeof(TextBox), TextBox.GotFocusEvent, new RoutedEventHandler(TextBox_GotFocus));
EventManager.RegisterClassHandler(typeof(TextBox), TextBox.PreviewMouseDownEvent, new MouseButtonEventHandler(TextBox_PreviewMouseDown));

Ответ 11

в файле App.xaml

<Application.Resources>
    <Style TargetType="TextBox">
        <EventSetter Event="GotKeyboardFocus" Handler="TextBox_GotKeyboardFocus"/>
    </Style>
</Application.Resources>

в файле App.xaml.cs

private void TextBox_GotKeyboardFocus(Object sender, KeyboardFocusChangedEventArgs e)
    {
        ((TextBox)sender).SelectAll();
    }

С помощью этого кода вы достигаете всего текстового поля в своем приложении.

Ответ 12

Взято из здесь:

Зарегистрировать глобальный обработчик событий в файле App.xaml.cs:

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),TextBox.GotFocusEvent,
    new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Тогда обработчик прост как:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Ответ 13

У меня есть немного упрощенный ответ для этого (только с событием PreviewMouseLeftButtonDown), который, похоже, имитирует обычные функции браузера:

В xaml у вас есть текстовое поле:

<TextBox Text="http://www.blabla.com" BorderThickness="2" BorderBrush="Green" VerticalAlignment="Center" Height="25"
                 PreviewMouseLeftButtonDown="SelectAll" />

В codebehind:

private void SelectAll(object sender, MouseButtonEventArgs e)
{

    TextBox tb = (sender as TextBox);

    if (tb == null)
    {
        return;
    }

    if (!tb.IsKeyboardFocusWithin)
    {
        tb.SelectAll();
        e.Handled = true;
        tb.Focus();
    }
}

Ответ 14

Я понимаю, что это очень старое, но вот мое решение, которое основано на пространствах имен выражений/взаимодействия Microsoft и взаимодействий.

Сначала я следовал инструкциям по этой ссылке, чтобы поместить триггеры интерактивности в стиль.

Тогда это сводится к этому

        <Style x:Key="baseTextBox" TargetType="TextBox">
        <Setter Property="gint:InteractivityItems.Template">
            <Setter.Value>
                <gint:InteractivityTemplate>
                    <gint:InteractivityItems>
                        <gint:InteractivityItems.Triggers>
                            <i:EventTrigger EventName="GotKeyboardFocus">
                                <ei:CallMethodAction MethodName="SelectAll"/>
                            </i:EventTrigger>
                            <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                                <ei:CallMethodAction MethodName="TextBox_PreviewMouseLeftButtonDown"
                                    TargetObject="{Binding ElementName=HostElementName}"/>
                            </i:EventTrigger>
                        </gint:InteractivityItems.Triggers>
                    </gint:InteractivityItems>
                </gint:InteractivityTemplate>
            </Setter.Value>
        </Setter>
    </Style>

и это

    public void TextBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        TextBox tb = e.Source as TextBox;
        if((tb != null) && (tb.IsKeyboardFocusWithin == false))
        {
            tb.Focus();
            e.Handled = true;
        }
    }

В моем случае, у меня есть пользовательский элемент управления, в котором находятся текстовые поля с выделенным кодом. Код позади имеет функцию обработчика. Я дал своему пользовательскому элементу управления имя в xaml, и я использую это имя для элемента. Это прекрасно работает для меня. Просто примените стиль к любому текстовому полю, где вы хотели бы, чтобы весь текст выделялся при щелчке в текстовом поле.

Первый CallMethodAction вызывает функцию SelectAll текстового поля, когда срабатывает событие GotKeyboardFocus в текстовом поле.

Надеюсь, это поможет.

Ответ 15

Для тех, кто интересуется подходом Donnelle/Groky, но нужно щелкнуть справа от последнего символа (но все еще внутри TextBox), чтобы поместить каретку в конец введенного текста, я придумал это решение

    int GetRoundedCharacterIndexFromPoint(TextBox textBox, Point clickedPoint)
    {
        int position = textBox.GetCharacterIndexFromPoint(clickedPoint, true);

        // Check if the clicked point is actually closer to the next character
        // or if it exceeds the righmost character in the textbox
        // (in this case return increase the position by 1)
        Rect charLeftEdge = textBox.GetRectFromCharacterIndex(position, false);
        Rect charRightEdge = textBox.GetRectFromCharacterIndex(position, true);
        double charWidth = charRightEdge.X - charLeftEdge.X;
        if (clickedPoint.X + charWidth / 2 > charLeftEdge.X + charWidth) position++;

        return position;
    }

    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 focused, give it the focus and
                // stop further processing of this click event.
                textBox.Focus();
                e.Handled = true;
            }
            else
            {
                int pos = GetRoundedCharacterIndexFromPoint(textBox, e.GetPosition(textBox));
                textBox.CaretIndex = pos;
            }
        }
    }

    void SelectAllText(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

Метод GetRoundedCharacterIndexFromPoint был взят из этой почты.

Ответ 16

    #region TextBoxIDCard selection
    private bool textBoxIDCardGotFocus = false;
    private void TextBoxIDCard_GotFocus(object sender, RoutedEventArgs e)
    {
        this.TextBoxIDCard.SelectAll();
    }

    private void TextBoxIDCard_LostFocus(object sender, RoutedEventArgs e)
    {
        textBoxIDCardGotFocus = false;
    }

    private void TextBoxIDCard_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (textBoxIDCardGotFocus == false)
        {
            e.Handled = true;
            this.TextBoxIDCard.Focus();
            textBoxIDCardGotFocus = true;
        }
    } 
    #endregion

Ответ 17

Попробуйте использовать этот метод расширения для добавления желаемого поведения в любой элемент управления TextBox. Я еще не тестировал его, но, похоже, он удовлетворяет мои потребности.

public static class TextBoxExtensions
{
    public static void SetupSelectAllOnGotFocus(this TextBox source)
    {
        source.GotFocus += SelectAll;
        source.PreviewMouseLeftButtonDown += SelectivelyIgnoreMouseButton;
    }

    private static void SelectAll(object sender, RoutedEventArgs e)
    {
        var textBox = e.OriginalSource as TextBox;
        if (textBox != null)
            textBox.SelectAll();
    }

    private static void SelectivelyIgnoreMouseButton(object sender, MouseButtonEventArgs e)
    {
        var textBox = (sender as TextBox);
        if (textBox != null)
        {
            if (!textBox.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                textBox.Focus();
            }
        }
    }
}

Ответ 18

У меня была такая же проблема. В VB.Net это так просто работает:

VB XAML:

<TextBox x:Name="txtFilterFrequency" />

Codehind:

Private Sub txtFilterText_GotFocus(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles txtFilterText.GotFocus
    Me.Dispatcher.BeginInvoke(Sub()
                                  txtFilterText.SelectAll()
                              End Sub, DispatcherPriority.ApplicationIdle, Nothing)
End Sub

С# (спасибо ViRuSTriNiTy)

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

Ответ 19

Я много искал для решения, я нашел пару решений для выбора. Но проблема в том, что мы делаем правый щелчок и делаем вырезание/копирование после выбора части текста из текстового поля, он выбирает все, даже я выбрал часть текст. Исправить это можно здесь. Просто добавьте приведенный ниже код в событие выбора клавиатуры. Это сработало для меня.

private static void SelectContentsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is TextBox)
    {
        TextBox textBox = d as TextBox;
        if ((e.NewValue as bool?).GetValueOrDefault(false))
        {
            textBox.GotKeyboardFocus += OnKeyboardFocusSelectText;                 
        }
        else
        {
            textBox.GotKeyboardFocus -= OnKeyboardFocusSelectText;

        }
    }
}


private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
{
    if (e.KeyboardDevice.IsKeyDown(Key.Tab))
        ((TextBox)sender).SelectAll();
}

Ответ 20

Я использовал ответ Нильса, но преобразован в более гибкий.

public enum SelectAllMode
{

    /// <summary>
    ///  On first focus, it selects all then leave off textbox and doesn't check again
    /// </summary>
    OnFirstFocusThenLeaveOff = 0,

    /// <summary>
    ///  On first focus, it selects all then never selects
    /// </summary>
    OnFirstFocusThenNever = 1,

    /// <summary>
    /// Selects all on every focus
    /// </summary>
    OnEveryFocus = 2,

    /// <summary>
    /// Never selects text (WPF default attitude)
    /// </summary>
    Never = 4,
}

public partial class TextBox : DependencyObject
{
    public static readonly DependencyProperty SelectAllModeProperty = DependencyProperty.RegisterAttached(
        "SelectAllMode",
        typeof(SelectAllMode?),
        typeof(TextBox),
        new PropertyMetadata(SelectAllModePropertyChanged));

    private static void SelectAllModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is System.Windows.Controls.TextBox)
        {
            var textBox = d as System.Windows.Controls.TextBox;

            if (e.NewValue != null)
            {
                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 = (System.Windows.Controls.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 System.Windows.Controls.TextBox))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }

        return parent;
    }

    private static void OnKeyboardFocusSelectText(object sender, KeyboardFocusChangedEventArgs e)
    {
        var textBox = e.OriginalSource as System.Windows.Controls.TextBox;
        if (textBox == null) return;

        var selectAllMode = GetSelectAllMode(textBox);

        if (selectAllMode == SelectAllMode.Never)
        {
            textBox.SelectionStart = 0;
            textBox.SelectionLength = 0;
        }
        else
            textBox.SelectAll();

        if (selectAllMode == SelectAllMode.OnFirstFocusThenNever)
            SetSelectAllMode(textBox, SelectAllMode.Never);
        else if (selectAllMode == SelectAllMode.OnFirstFocusThenLeaveOff)
            SetSelectAllMode(textBox, null);
    }

    [AttachedPropertyBrowsableForChildrenAttribute(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(System.Windows.Controls.TextBox))]
    public static SelectAllMode? GetSelectAllMode(DependencyObject @object)
    {
        return (SelectAllMode)@object.GetValue(SelectAllModeProperty);
    }

    public static void SetSelectAllMode(DependencyObject @object, SelectAllMode? value)
    {
        @object.SetValue(SelectAllModeProperty, value);
    }
}

В XAML вы можете использовать как один из них:

<!-- On first focus, it selects all then leave off textbox and doesn't check again -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenLeaveOff" />

<!-- On first focus, it selects all then never selects -->
<TextBox attprop:TextBox.SelectAllMode="OnFirstFocusThenNever" />

<!-- Selects all on every focus -->
<TextBox attprop:TextBox.SelectAllMode="OnEveryFocus" />

<!-- Never selects text (WPF default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />

Ответ 21

Это, безусловно, самое простое решение.

Добавить глобальный обработчик в приложение (App.xaml.cs) и готово. Вам понадобится всего несколько строк кода.

protected override void OnStartup(StartupEventArgs e)
{
    EventManager.RegisterClassHandler(typeof(TextBox),
        TextBox.GotFocusEvent,
        new RoutedEventHandler(TextBox_GotFocus));

    base.OnStartup(e);
}

Поэтому используйте класс EventManager, чтобы зарегистрировать глобальный обработчик события для типа (TextBox). Фактический обработчик очень прост:

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    (sender as TextBox).SelectAll();
}

Проверьте здесь: WPF TextBox SelectAll on Focus

Надеюсь, поможет.

Ответ 22

Вот версия ответа на С#, опубликованная @Nasenbaer

private delegate void TextBoxSelectAllDelegate(object sender);

private void TextBoxSelectAll(object sender)
{
    (sender as System.Windows.Controls.TextBox).SelectAll();
}

private void MyTextBox_GotFocus(object sender, System.Windows.RoutedEventArgs e)
{
    TextBoxSelectAllDelegate d = TextBoxSelectAll;

    this.Dispatcher.BeginInvoke(d,
        System.Windows.Threading.DispatcherPriority.ApplicationIdle, sender);
}

тогда как MyTextBox_GotFocus - это обработчик события, назначенный событию GotFocus MyTextBox.

Ответ 23

Кажется, это хорошо работает для меня. Это в основном резюме некоторых ранних сообщений. Я просто поместил это в свой файл MainWindow.xaml.cs в конструкторе. Я создаю два обработчика, один для клавиатуры и один для мыши, и вставляю оба события в одну и ту же функцию, HandleGotFocusEvent, которая определяется сразу после конструктора в том же файле.

public MainWindow()
{
   InitializeComponent();

   EventManager.RegisterClassHandler(typeof(TextBox), 
      UIElement.GotKeyboardFocusEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);
   EventManager.RegisterClassHandler(typeof(TextBox),
      UIElement.GotMouseCaptureEvent,
      new RoutedEventHandler(HandleGotFocusEvent), true);   
}
private void HandleGotFocusEvent(object sender, RoutedEventArgs e)
{
   if (sender is TextBox)
      (sender as TextBox).SelectAll();
}

Ответ 24

Простой способ переопределить mouseDown и выбрать все после doubleclick:

public class DoubleClickTextBox: TextBox
{

    public override void EndInit()
    {
        base.EndInit();            
    }

    protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        this.Cursor = Cursors.Arrow;
    }
    protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
    {

    }

    protected override void OnMouseDoubleClick(System.Windows.Input.MouseButtonEventArgs e)
    {
        base.OnMouseDown(e);
        this.SelectAll();
    }
}

Ответ 25

Попробуйте поместить это в конструктор любого элемента управления, где находится ваше текстовое поле:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}

Ответ 26

Сергей.

После поиска и тестирования я нашел простое решение, которое сработало для меня.

Вам нужно добавить обработчик события в "Загруженное" событие окна вашего контейнера:

    private void yourwindow_Loaded(object sender, RoutedEventArgs e)
    {
        EventManager.RegisterClassHandler(typeof(TextBox),
            TextBox.PreviewMouseLeftButtonDownEvent,
            new RoutedEventHandler(SelectivelyIgnoreMouseButton));
    }

Затем вам нужно создать обработчик в указанном RoutedEventHandler в предыдущем коде:

    private void SelectivelyIgnoreMouseButton(object sender, RoutedEventArgs e)
    {
        TextBox tb = (sender as TextBox);
        if (tb != null)
        {
            if (!tb.IsKeyboardFocusWithin)
            {
                e.Handled = true;
                tb.Focus();
            }
        }
    }

Теперь вы можете добавить команду SelectAll() в обработчики событий GotFocus к любым элементам управления TextBox отдельно:

    private void myTextBox_GotFocus(object sender, RoutedEventArgs e)
    {
        (sender as TextBox).SelectAll();
    }

Теперь ваш текст выбран в фокусе!

Адаптировано из Dr. WPF, форумы MSDN

Ответ 27

Я тестировал все из них, но только следующее:

        protected override void OnStartup(StartupEventArgs e) 
        {
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.PreviewMouseLeftButtonDownEvent,
           new MouseButtonEventHandler(SelectivelyHandleMouseButton), true);
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotKeyboardFocusEvent,
              new RoutedEventHandler(SelectAllText), true);
            EventManager.RegisterClassHandler(typeof(TextBox), UIElement.GotFocusEvent,
              new RoutedEventHandler(GotFocus), true);          
        }

        private static void SelectivelyHandleMouseButton(object sender, MouseButtonEventArgs e)
        {
            var textbox = (sender as TextBox);
            if (textbox != null)
            {
                int hc = textbox.GetHashCode();
                if (hc == LastHashCode)
                {
                    if (e.OriginalSource.GetType().Name == "TextBoxView")
                    {
                        e.Handled = true;
                        textbox.Focus();
                        LastHashCode = -1;
                    }
                }
            }
            if (textbox != null) textbox.Focus();
        }

        private static void SelectAllText(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                textBox.SelectAll();
        }

        private static int LastHashCode;
        private static void GotFocus(object sender, RoutedEventArgs e)
        {
            var textBox = e.OriginalSource as TextBox;
            if (textBox != null)
                LastHashCode = textBox.GetHashCode();
        }

Ответ 28

WOW! Прочитав все вышеизложенное, я оказался переполненным и смущенным. Я взял то, что, как я думал, узнал в этом посте, и попробовал что-то совершенно другое. Чтобы выбрать текст в текстовом поле, когда он получает фокус, я использую это:

private void TextField_GotFocus(object sender, RoutedEventArgs e)
{
    TextBox tb = (sender as Textbox);
    if(tb != null)
    {
        e.Handled = true;
        tb.Focus();
        tb.SelectAll();
    }
}

Задайте для этого метода свойство GotFocus текстового поля.

Запуск приложения и однократное нажатие в текстовом поле выделяет все, что уже есть в текстовом поле.

Если действительно, целью является выбор текста при щелчке пользователем в текстовом поле, это кажется простым и включает в себя гораздо меньше кода. Просто говорю...