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


232

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

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

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

Если у вас будет более одной формы, ее ответ продолжает становиться менее сложным, чем первый. Удобство использования обоих вариантов является спорным, поскольку вы можете изменить работу любого из них.
thepaulpage

1
@ Сергей: Вы можете изменить принятый ответ на этот вопрос, так как с тех пор были лучшие ответы. Я не собираюсь предлагать мой, но вы могли бы;)
Grokys

Вопрос имеет тег Silverlight, но Silverlight не имеет большинства событий / каких-либо предварительных событий вообще. Какое решение тогда следует использовать для серебряного света?
Валентин Кузуб

Ссылка "Почему фокус в WPF такой хитрый?" сломан
Максенс

1
как упоминалось в комментарии к stackoverflow.com/a/2553297/492 ниже, madprops.org/blog/wpf-textbox-selectall-on-focus является простым решением и сохраняет исходное поведение nouse. Я поместил регистрацию событий в конструктор, потому что у меня только один элемент управления WPF в приложении.
CAD bloke

Ответы:


75

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

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


10
Нет. При щелчке мышью в середине существующего текста - выбор теряется, как только кнопка мыши отпущена.
Сергей Алдоухов

3
Хотя - после второго одиночного щелчка, он снова выбирает весь текст ... Не уверен, что это намеренное поведение от дизайнеров WPF, но удобство использования не так уж и плохо. Еще одно отличие от одного обработчика GotFocus заключается в том, что нажатие на пустое место в TextBox действительно выделяет все.
Сергей Алдоухов

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

1
Еще один недостаток этого решения - при использовании меню «Вырезать / Копировать / Вставить» в TextBox весь текст выделяется при выборе любого пункта меню.

@gcores Я знаю, что это старый, но кто-нибудь знает, почему в событии GotFocus выбранный текст теряется? Вы правы в том, что это работает в других событиях, и это вполне приемлемое решение в моей книге.
Притвориться

210

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

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

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

9
Большое спасибо за это. Это прекрасно работает и должен быть принятым ответом ИМХО. Приведенный выше код работает, когда TextBox получает фокус с помощью клавиатуры или мыши (и, видимо, стилуса). +1
Дрю Ноакс

5
Я видел почти идентичный ответ здесь social.msdn.microsoft.com/Forums/en-US/wpf/thread/… , он работает также, как и когда он не использует e.OriginalSource и не сканирует визуальное дерево. Есть ли преимущество в этом?
Марко Луглио

1
Прекрасно работает, но было бы идеально, если бы он позволял выделять текст с помощью мыши. Адресная строка Google Chrome - прекрасный пример идеальной системы: если пользователь щелкает и отпускает без перетаскивания, весь текст выделяется. Однако, если пользователь щелкает и перетаскивает, перетаскивание выделяет текст, как правило, без выделения всего. SelectAll происходит только при отпускании мыши . Я возьму и посмотрю, смогу ли я вообще улучшить этот дизайн.
devios1

2
Еще один недостаток этого решения - при использовании меню «Вырезать / Копировать / Вставить» в TextBox весь текст выделяется при выборе любого пункта меню.

1
Я обнаружил, что дополнительный тест в SelectAllTextметоде textBox.IsFocusedулучшает его. Вы не хотите выбирать все, когда GetKeyboardFocusиз-за alt-tabbing в программу.
Скотт Стаффорд

164

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

Вместо этого я регистрирую обработчики в App.xaml.cs для всех TextBoxes в приложении. Это позволяет мне использовать ответ Доннелле со стандартным элементом управления 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
Это довольно крутое решение, оно также было описано Мэттом Гамильтоном давным-давно здесь: madprops.org/blog/wpf-textbox-selectall-on-focus
Эшли Дэвис,

Получил несколько орфографических ошибок в слове «получает», «сфокусирован»
Нейт Заугг

2
Спасибо, Нейт, поправил, хотя в свою защиту я хотел бы отметить, что орфографические ошибки были скопированы дословно из ответа
Доннеллы

Вопрос имеет тег Silverlight, но Silverlight не имеет большинства событий / каких-либо предварительных событий вообще. Какое решение тогда следует использовать для серебряного света? заранее спасибо
Валентин Кузуб

4
«Сосредоточенная орфография гораздо чаще встречается в США, однако иногда она используется в Великобритании и Канаде и особенно распространена в Австралии и Новой Зеландии». Так Nyah;)
Donnelle

85

Это довольно старый, но я все равно покажу свой ответ.

Я выбрал часть ответа Доннелла (пропустил двойной щелчок), потому что считаю его более естественным. Однако, как и gcores, мне не нравится необходимость создавать производный класс. Но мне также не нравится OnStartupметод gcores . И мне это нужно на «в общем, но не всегда».

Я реализовал это как прикрепленный, DependencyPropertyчтобы я мог установить local:SelectTextOnFocus.Active = "True"в xaml. Я считаю этот способ наиболее приятным.

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

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


8
+1 это намного лучше, чем глобальная настройка, и это больше «путь WPF», чем вывод из TextBox.
Стийн

3
+1 согласен со стайн. «Скрывать» свой код в app.cs нехорошо для бедного разработчика, который должен выяснить, почему происходит SelectAllOnFocus. :-) Я просто поместил это в свой класс для TextBoxBehaviors, а затем обновил свой базовый стиль TextBox. Работал лакомство Приветствия
Ли Кэмпбелл

2
@tronda: просто добавьте стиль к ресурсам, используя TargetType для TextBox. Я предлагаю вам взглянуть на wpftutorial.net/Styles.html
Нильс

2
Еще +1 за лучший ответ. Единственная проблема, которую я нахожу в том, что текст всегда выделяется, даже когда я использую правую кнопку мыши - что я часто делаю, чтобы редактировать текст через контекстное меню - решение для этого случая не работает, потому что оно всегда выделяет весь текст, даже если я просто хотел вырезать 1 слово через контекстное меню. Ребята, вы знаете, как это исправить?
user3313608

2
Мне нравится этот ответ, но почему вы должны расширить DependencyObject? Я удалил это, и это все еще отлично работает.
Фред

47

Вот варианты поведения Blend, реализующие решение для ответа:

Один для прикрепления к одному TextBox:

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

Это, безусловно, лучшее и самое чистое решение. Большое спасибо за то, что поделились этим.
Голвеллиус

Это выглядит действительно красиво, но по какой-то причине нарушает управление вкладками ... Есть идеи, почему?
Марк

Я хотел бы использовать ваше решение. Но действительно потерял ... может быть, у вас есть образец?
Хуан Пабло Гомес

Когда вы щелкаете где-то в текстовом поле, имея фокус (представьте, что вы хотите переместить каретку в другое место), он снова выберет AllAll вместо перемещения каретки. Это неожиданно. Исправлено путем замены GotMouseCapture на MouseDoubleClick, что является распространенным явлением. Благодаря последним решениям от MSDN.
Норехов,

1
Кажется, он не работает, когда текстовое поле получает начальный фокус через FocusManager.FocusedElement. Есть идеи почему?
Szx

24

Хотя это старый вопрос, я только что столкнулся с этой проблемой, но решил ее, используя присоединенное поведение, а не поведение выражения, как в ответе Сергея. Это означает , что я не нужна зависимость от System.Windows.Interactivityв Бленд 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"/>

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


Мне нравится этот подход, но методы Get / Set не должны заканчиваться на «Свойство»; Мне пришлось удалить это, чтобы компилировать код после добавления части Xaml.
Патрик Квирк

Очень хорошо, работал так, как ожидалось. Мне это нравится, потому что это помогает мне разделить проблемы View при работе с MVVM.
Killnine

16

Вот очень хорошее очень простое решение для 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();
        }
    }
}

1
По сути, это то же решение, что и самое рейтинговое в этой теме. Но так как это двумя годами ранее, теперь я знаю, откуда у @Donnelle его позаимствовали;)
Сергей Алдоухов

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

10

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

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. Я обнаружил код ниже где-то (кредит предоставляется), и он работает хорошо. Я публикую его, хотя он не имеет прямого отношения к вопросу ОП, поскольку демонстрирует ту же модель использования Dispatcherдля работы с a 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);
}

Я думаю, это самый простой способ для реализации. после создания метода расширения вам просто нужно вызвать myTextBox.SelectAllText (). Почему этот ответ не получил больше очков? почему другие решения намного лучше?
Тоно Нам

2
Я бы избегал этого метода, потому что он полагается на асинхронный вызов для запуска после обработчика MouseUp текстового поля. Я бы не поверил, что это на 100% детерминировано и может привести к непоследовательному поведению Даже если это вряд ли произойдет, я бы предпочел использовать более надежные методы, описанные выше.
Роб Х

6

Вот попытка решить некоторые проблемы с другими решениями:

  1. При использовании контекстного меню правой кнопкой мыши для вырезки / копирования / вставки выделяется весь текст, даже если вы не выбрали все это.
  2. При возврате из контекстного меню правой кнопкой мыши, весь текст всегда выделен.
  3. При возврате в приложение с Alt+ Tabвесь текст всегда выделяется.
  4. При попытке выделить только часть текста при первом нажатии все всегда выбирается (в отличие, например, от адресной строки Google chromes).

Код, который я написал, настраивается. Вы можете выбрать на какие действия выбрать все поведение должно происходить путем установки трех полей: только для чтения SelectOnKeybourdFocus, SelectOnMouseLeftClick, SelectOnMouseRightClick.

Недостатком этого решения является то, что оно более сложное и статическое состояние сохраняется. Это кажется уродливой борьбой со стандартным поведением TextBoxконтроля. Тем не менее, это работает, и весь код скрыт в классе контейнера Attached Property.

public static class TextBoxExtensions
{
    // Configuration fields to choose on what actions the select all behavior should occur.
    static readonly bool SelectOnKeybourdFocus = true;
    static readonly bool SelectOnMouseLeftClick = true;
    static readonly bool SelectOnMouseRightClick = true;

    // Remembers a right click context menu that is opened 
    static ContextMenu ContextMenu = null;

    // Remembers if the first action on the TextBox is mouse down 
    static bool FirstActionIsMouseDown = false;

    public static readonly DependencyProperty SelectOnFocusProperty =
        DependencyProperty.RegisterAttached("SelectOnFocus", typeof(bool), typeof(TextBoxExtensions), new PropertyMetadata(false, new PropertyChangedCallback(OnSelectOnFocusChanged)));

    [AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
    [AttachedPropertyBrowsableForType(typeof(TextBox))]
    public static bool GetSelectOnFocus(DependencyObject obj)
    {
        return (bool)obj.GetValue(SelectOnFocusProperty);
    }

    public static void SetSelectOnFocus(DependencyObject obj, bool value)
    {
        obj.SetValue(SelectOnFocusProperty, value);
    }

    private static void OnSelectOnFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox)) return;

        if (GetSelectOnFocus(textBox))
        {
            // Register events
            textBox.PreviewMouseDown += TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp += TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus += TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus += TextBox_LostKeyboardFocus;
        }
        else
        {
            // Unregister events
            textBox.PreviewMouseDown -= TextBox_PreviewMouseDown;
            textBox.PreviewMouseUp -= TextBox_PreviewMouseUp;
            textBox.GotKeyboardFocus -= TextBox_GotKeyboardFocus;
            textBox.LostKeyboardFocus -= TextBox_LostKeyboardFocus;
        }
    }

    private static void TextBox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // If mouse clicked and focus was not in text box, remember this is the first click.
        // This will enable to prevent select all when the text box gets the keyboard focus 
        // right after the mouse down event.
        if (!textBox.IsKeyboardFocusWithin)
        {
            FirstActionIsMouseDown = true;
        }
    }

    private static void TextBox_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnMouseLeftClick/SelectOnMouseRightClick is true and left/right button was clicked
        // 3) This is the first click
        // 4) No text is selected
        if (((SelectOnMouseLeftClick && e.ChangedButton == MouseButton.Left) || 
            (SelectOnMouseRightClick && e.ChangedButton == MouseButton.Right)) &&
            FirstActionIsMouseDown &&
            string.IsNullOrEmpty(textBox.SelectedText))
        {
            textBox.SelectAll();
        }

        // It is not the first click 
        FirstActionIsMouseDown = false;
    }

    private static void TextBox_GotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Select all only if:
        // 1) SelectOnKeybourdFocus is true
        // 2) Focus was not previously out of the application (e.OldFocus != null)
        // 3) The mouse was pressed down for the first after on the text box
        // 4) Focus was not previously in the context menu
        if (SelectOnKeybourdFocus &&
            e.OldFocus != null &&
            !FirstActionIsMouseDown &&
            !IsObjectInObjectTree(e.OldFocus as DependencyObject, ContextMenu))
        {
            textBox.SelectAll();
        }

        // Forget ContextMenu
        ContextMenu = null;
    }

    private static void TextBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
    {
        if (!(sender is TextBox textBox)) return;

        // Remember ContextMenu (if opened)
        ContextMenu = e.NewFocus as ContextMenu;

        // Forget selection when focus is lost if:
        // 1) Focus is still in the application
        // 2) The context menu was not opened
        if (e.NewFocus != null
            && ContextMenu == null)
        {
            textBox.SelectionLength = 0;
        }
    }

    // Helper function to look if a DependencyObject is contained in the visual tree of another object
    private static bool IsObjectInObjectTree(DependencyObject searchInObject, DependencyObject compireToObject)
    {
        while (searchInObject != null && searchInObject != compireToObject)
        {
            searchInObject = VisualTreeHelper.GetParent(searchInObject);
        }

        return searchInObject != null;
    }
}

Чтобы прикрепить Attached Property к a TextBox, все, что вам нужно сделать, это добавить пространство имен xml ( xmlns) Attached Property, а затем использовать его следующим образом:

<TextBox attachedprop:TextBoxExtensions.SelectOnFocus="True"/>

Некоторые замечания об этом решении:

  1. Чтобы переопределить стандартное поведение события нажатия мыши и включить выделение только части текста при первом щелчке, весь текст выделяется при событии мыши вверх.
  2. Мне пришлось иметь дело с тем, что он TextBoxпомнит свой выбор после того, как теряет фокус. Я фактически переопределил это поведение.
  3. Я должен был вспомнить, является ли нажатие кнопки мыши первым действием на TextBox( FirstActionIsMouseDownстатическое поле).
  4. Я должен был вспомнить контекстное меню, открываемое по щелчку правой кнопкой мыши ( ContextMenuстатическое поле).

Единственный побочный эффект, который я обнаружил, это когда SelectOnMouseRightClickэто правда. Иногда контекстное меню, вызываемое правой кнопкой мыши, мерцает, когда его открывают, а щелчок правой кнопкой мыши на пустом месте TextBoxне делает «выбрать все».


5

Я не нашел ни одного из представленных здесь ответов, имитирующих стандартное текстовое поле 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;
    }
}

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


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

1
Сергей: первый щелчок выберет все значение, второй щелчок установит курсор справа от значения. В других представленных решениях при втором щелчке будет сохранено все выбранное значение, что затрудняет добавление к значению.
Кристоф Вербиест

Как это используется? Я добавил этот код в App.xaml.cs, но он, похоже, не влиял на текстовые поля в моем приложении.
Пинтег

5

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

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

4

В файле 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();
}

С этим кодом вы достигаете всего TextBoxв вашем приложении.


3

Взято отсюда :

Зарегистрируйте глобальный обработчик событий в файле 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();
}

3

Я понимаю, что это очень старо, но вот мое решение, которое основано на пространствах имен выражений / взаимодействия 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, и я использую это имя для элемента. Это работает отлично для меня. Просто примените стиль к любому месту, TextBoxгде вы хотели бы, чтобы весь текст был выделен при нажатии на TextBox.

Первый CallMethodActionвызывает метод текстового поля, SelectAllкогда происходит GotKeyboardFocusсобытие TextBox.

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


Поскольку это такие старые вопросы, это может помочь вашему ответу привлечь внимание, если вы упомянете, почему кто-то может выбрать этот подход.
Дивибизан

Во-первых, это не нужно вводить в стиль, но я думаю, что очевидно, что есть много элементов управления текстовыми полями, которые нуждаются в этом, стиль - это путь.
wiyosaya

1
Возможно, некоторые не согласятся с этим подходом, однако, относительно того, почему вы можете использовать этот подход, он не требует создания подкласса TextBox, регистрации событий обработчика класса, методов расширения, создания вложенных свойств и т. Д. Как стиль, он также может быть добавлен. в словарь ресурсов любого проекта xaml. Без ключа x: он будет применяться к любому экземпляру TextBox в области словаря ресурсов без необходимости изменять xaml каждого отдельного текстового поля. В некоторых случаях это может быть более чистый подход.
wiyosaya

2

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

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's 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's default attitude) -->
<TextBox attprop:TextBox.SelectAllMode="Never" />

1
Действительно хорошее решение для использования в шаблонах, так как вы можете связать его с xaml без какого-либо реального кода, просто расширенное поведение текстового поля.
Эрик Йоханссон

2

Вот версия ответа на C #, опубликованная @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.


2

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

В XAML вы TextBoxговорите:

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

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

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

1
Возможно, вы захотите добавить событие GotKeyboardFocus с TextBox.SelectAll () внутри для людей, которые перемещаются по вашему приложению. Ваше решение работает и для PasswordBoxes (так как PasswordBoxes являются закрытыми типами, они не могут быть расширены).
Дэвид Шеррет

1

Попробуйте этот метод расширения, чтобы добавить желаемое поведение к любому элементу управления 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();
            }
        }
    }
}

1

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

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

1

У меня была такая же проблема. В 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

C # (спасибо 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);
}

Лучшее решение для меня, я разместил перевод на C # здесь: stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy

Для меня такой подход иногда не позволяет выбрать текст. Я думаю, что это состояние гонки из-за BeginInvoke.
Ваймс

Пожалуйста уточни. Приоритет диспетчера работает с приложениями по умолчанию, как и ожидалось. Какова ваша ситуация? Вы пытались точно, как описано? Что-нибудь особенное в вашем решении?
Насенбаер

1

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

Добавить глобальный обработчик в приложение (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

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


1

Для тех, кто интересуется подходом Доннелла / Гроки, но хочет щелкнуть справа от последнего символа (но все еще внутри 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Метод был взят из этого поста.


1
Работает нормально, но событие двойного щелчка не срабатывает
Родриго Кабальеро

На самом деле он входит в событие doubleclick, но свойство OriginalSource имеет тип TextBoxView. Поэтому метод SelectAllText должен выглядеть следующим образом: private static void SelectAllText (отправитель объекта, RoutedEventArgs e) {var textBox = e.OriginalSource as TextBox; if (textBox! = null) {textBox.SelectAll (); System.Diagnostics.Debug.WriteLine («Выбрано ВСЕ»); } else if (отправитель - TextBox) {(отправитель как TextBox) .SelectAll (); }
Родриго Кабальеро

1

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

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

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


Я просто использовал: private async void TBTime_GotFocus (отправитель объекта, RoutedEventArgs e) {TextBox tb = (TextBox) e.OriginalSource; await Dispatcher.RunAsync (Windows.UI.Core.CoreDispatcherPriority.Normal, async () => {tb.SelectAll ();}); }
Дэвид Джонс

1
#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

Если у вас есть 20 текстовых полей в окне, вы будете создавать 3 метода для каждого текстового поля? Этот подход не хорош. Взгляните сюда: rachel53461.wordpress.com/2011/11/05/…
Александру Дику

0

Это, кажется, работает хорошо для меня. Это в основном резюме некоторых предыдущих постов. Я просто поместил это в мой файл 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();
}

Красиво и легко, но, похоже, есть проблема с синхронизацией - при каждой другой попытке (щелчок мышью) он сразу отменяет выбор ...?
T4NK3R

0

Простой способ переопределить mouseDown и выбрать все после двойного щелчка:

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

0

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

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

Этот подход не работает, когда вы помещаете это в конструктор окон.
ВИРУСТРИНИКА

0

Если есть событие, которое отменяет OnFocusвыделение текста при наведении мыши, я обычно просто откладываю выделение всех.

private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
    if (TextBox.Text != null)
    {
        _ = Task.Run(() =>
        {
            Dispatcher.Invoke(
                async () => {
                    await Task.Delay(100);
                    TextBox.SelectAll();
                }
            );
        });
    }
}

-1

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

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

4
Это также непристойное использование хеш-кодов. Я прочитал бы это, ссылка
RichK

3
И использовать GetType().Nameвместо isили asдовольно
хакерский

-1

Я вижу, что есть много ответов, но как утвержденный, методы, которые следует использовать, EditTextBoxGotCapture

со следующим кодом:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.