Como selecionar automaticamente todo o texto em foco no WPF TextBox?

232

Se eu ligar SelectAllde um GotFocusmanipulador de eventos, ele não funcionará com o mouse - a seleção desaparece assim que o mouse é liberado.

EDIT: As pessoas estão gostando da resposta de Donnelle, tentarei explicar por que não gostei tanto quanto a resposta aceita.

  • É mais complexo, enquanto a resposta aceita faz a mesma coisa de uma maneira mais simples.
  • A usabilidade da resposta aceita é melhor. Quando você clica no meio do texto, o texto fica desmarcado quando você solta o mouse, permitindo que você comece a editar instantaneamente e, se ainda deseja selecionar tudo, basta pressionar o botão novamente e desta vez não será desmarcado na liberação. Seguindo a receita de Donelle, se eu clicar no meio do texto, tenho que clicar pela segunda vez para poder editar. Se clicar em algum lugar dentro do texto e fora dele, provavelmente significa que quero começar a editar em vez de substituir tudo.
Sergey Aldoukhov
fonte
Se você tiver mais de um formulário, a resposta dela continuará a ser menos complexa que a primeira. A usabilidade de ambas as opções é discutível, pois você pode alterar a maneira como elas funcionam.
thepaulpage
1
@ Emery: Você pode querer alterar a resposta aceita para esta pergunta, pois houve respostas melhores desde então. Eu não vou sugerir a minha, mas você podia;)
Grokys
A pergunta tem a tag Silverlight, mas o Silverlight não possui a maioria dos eventos / nenhum tipo de visualização de eventos. Qual solução deve ser usada para o silverlight?
Valentin Kuzub 5/10/11
Link "Por que o foco no WPF é tão complicado?" está quebrado
Maxence 13/05
1
Como mencionado em um comentário em stackoverflow.com/a/2553297/492 abaixo, madprops.org/blog/wpf-textbox-selectall-on-focus é uma solução fácil e preserva o comportamento original do nouse. Coloquei o registro de eventos no construtor porque só tenho um controle WPF no aplicativo.
CAD bloke

Respostas:

75

Não sei por que ele perde a seleção no GotFocusevento.

Mas uma solução é fazer a seleção GotKeyboardFocusdos GotMouseCaptureeventos e. Dessa forma, sempre funcionará.

gcores
fonte
10
Não. Quando clicada com o mouse no meio do texto existente - a seleção é perdida assim que o botão do mouse é liberado.
Sergey Aldoukhov 19/03/09
3
Embora - após um segundo clique único, ele selecione todo o texto novamente ... Não tenho certeza se é um comportamento pretendido pelos designers do WPF, mas a usabilidade não é tão ruim. Outra diferença de um único manipulador do GotFocus é que clicar em um espaço vazio no TextBox seleciona tudo.
Sergey Aldoukhov 19/03/09
3
Esta foi a minha primeira solução também. Mas descobri que os usuários estão realmente ficar irritado, quando eles são incapazes de selecionar texto usando o mouse, porque toda vez que eles clique todo o texto é selecionado ...
Nils
1
Uma desvantagem adicional desta solução é quando você usa o menu "Recortar / Copiar / Colar" do TextBox, o texto inteiro é selecionado quando você seleciona qualquer item de menu.
@gcores Eu sei que isso é antigo, mas alguém sabe por que, no evento GotFocus, o texto selecionado é perdido? Você está certo sobre isso trabalhando em outros eventos, e essa é uma solução perfeitamente aceitável no meu livro.
Fingir
210

Temos isso para que o primeiro clique selecione tudo e outro clique vá para o cursor (nosso aplicativo foi projetado para uso em tablets com canetas).

Você pode achar util.

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();
    }
}
Donnelle
fonte
9
Muito obrigado por isso. Isso funciona maravilhosamente e deve ser a resposta aceita IMHO. O código acima funciona quando o TextBox recebe foco via teclado ou mouse (e aparentemente caneta). +1
Drew Noakes
5
Vi uma resposta quase idêntica aqui social.msdn.microsoft.com/Forums/en-US/wpf/thread/… , funciona também, mas não usa e.OriginalSource, nem rasteja pela árvore visual. Existe alguma vantagem em fazer tudo isso?
Marco Luglio 27/07/2009
1
Funciona muito bem, mas seria perfeito se ainda permitisse a seleção de arrastar o texto com o mouse. A barra de endereços do Google Chrome é um exemplo perfeito do sistema ideal: se o usuário clicar e soltar sem arrastar, o texto inteiro será destacado. No entanto, se o usuário clicar e arrastar, o arrasto seleciona o texto normalmente sem selecionar todos. O SelectAll ocorre apenas na liberação do mouse . Vou mexer e ver se consigo melhorar esse design.
precisa saber é o seguinte
2
Uma desvantagem adicional desta solução é quando você usa o menu "Recortar / Copiar / Colar" do TextBox, o texto inteiro é selecionado quando você seleciona qualquer item de menu.
1
Eu descobri que um teste adicional no SelectAllTextmétodo de textBox.IsFocusedmelhora. Você não deseja selecionar tudo quando isso GetKeyboardFocusocorrer devido às abas alternativas no programa.
Scott Stafford
164

A resposta de Donnelle funciona melhor, mas ter que derivar uma nova classe para usá-la é uma dor.

Em vez de fazer isso, registro os manipuladores em App.xaml.cs para todos os TextBoxes no aplicativo. Isso me permite usar a resposta de Donnelle com o controle TextBox padrão.

Adicione os seguintes métodos ao seu 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();
    }
}
Grokys
fonte
4
Esta é uma solução muito legal, foi também descrito por Matt Hamilton há séculos aqui: madprops.org/blog/wpf-textbox-selectall-on-focus
Ashley Davis
Ocorreu um erro de ortografia em 'recebe', 'focado'
Nate Zaugg
2
Graças Nate, corrigido, embora em minha defesa que eu gostaria de destacar a ortografia erros foram copiados textualmente a resposta de Donnelle;)
Grokys
A pergunta tem a tag Silverlight, mas o Silverlight não possui a maioria dos eventos / nenhum tipo de visualização de eventos. Qual solução deve ser usada para o silverlight? Agradecemos antecipadamente
Valentin Kuzub 05/10
4
"A ortografia focada é muito mais comum nos EUA; no entanto, a ortografia focada às vezes é usada no Reino Unido e no Canadá, e é especialmente comum na Austrália e na Nova Zelândia." Então nyah;)
Donnelle
85

Isso é bastante antigo, mas mostrarei minha resposta de qualquer maneira.

Escolhi parte da resposta de Donnelle (pulei o clique duplo) porque acho isso mais natural. No entanto, como gcores, não gosto da necessidade de criar uma classe derivada. Mas eu também não gosto do OnStartupmétodo gcores . E eu preciso disso em uma base "geralmente, mas nem sempre".

Eu implementei isso como um anexo DependencyPropertypara que eu possa definir local:SelectTextOnFocus.Active = "True"no xaml. Acho assim o mais agradável.

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

Para o meu recurso "geral, mas nem sempre", defino esta propriedade Attache como Trueem (global) TextBox Style. Dessa forma, "selecionar o texto" está sempre "ativado", mas posso desativá-lo por caixa de texto.

Nils
fonte
8
Com +1, isso é muito melhor do que configurá-lo globalmente, e é mais "a maneira WPF" do que derivar do TextBox.
stijn
3
+1 Concordo com stijn. "Ocultar" seu código no app.cs não é bom para o pobre desenvolvedor que precisa descobrir por que o SelectAllOnFocus está acontecendo. :-) Acabei de colocar isso na minha classe para TextBoxBehaviors e atualizei meu estilo TextBox base. Trabalhou um prazer. Cheers
Lee Campbell
2
@tronda: basta adicionar um estilo aos recursos usando um TargetType de TextBox. Eu sugiro que você dê uma olhada no wpftutorial.net/Styles.html
Nils
2
Outro +1 para a melhor resposta. O único problema que encontro é que o texto é sempre selecionado mesmo quando uso o botão direito do mouse - o que costumo editar para editar o texto pelo menu de contexto - a solução não funciona nesse caso, porque sempre seleciona todo o texto, mesmo que eu só queria cortar 1 palavra através do menu de contexto. Vocês sabem como consertar isso?
user3313608
2
Eu gosto desta resposta, mas por que você precisa estender o DependencyObject? Eu removi isso e ainda funciona bem.
Fred
47

Aqui estão os comportamentos do Blend implementando a solução de resposta para sua conveniência:

Um para anexar a um único 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;
        }
    }
}

E um para anexar à raiz de um contêiner contendo vários TextBox'es:

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();
    }
}
Sergey Aldoukhov
fonte
Esta é de longe a melhor e mais limpa solução. Muito obrigado por compartilhá-lo.
Golvellius
Parece muito bom, mas por algum motivo ele quebra o controle da guia ... Alguma idéia do porquê?
Marc
Eu gostaria de usar sua solução. Mas realmente perdido ... talvez você tenha uma amostra?
Juan Pablo Gomez
Quando você clica em algum lugar da caixa de texto enquanto mantém o foco (imagine que deseja mover o cursor para outro local), ele selecionará Todos novamente novamente em vez de mover o cursor. É inesperado. Corrigido, substituindo GotMouseCapture por MouseDoubleClick, que é comum. Graças às últimas soluções do MSDN.
Norekhov 04/04
1
Parece não funcionar quando a caixa de texto recebe o foco inicial via FocusManager.FocusedElement. Alguma idéia do porquê?
Szx
24

Embora essa seja uma pergunta antiga, acabei de ter esse problema, mas o resolvi usando um comportamento anexado, em vez de um comportamento de expressão, como na resposta de Sergey. Isso significa que não preciso de uma dependência no System.Windows.InteractivityBlend 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();
    }
}

Você pode usá-lo no seu XAML assim:

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

Eu escrevi sobre isso aqui .

Deveres
fonte
Eu gosto dessa abordagem, mas os métodos Get / Set não devem terminar em "Propriedade"; Eu tive que removê-lo para obter o código compilado depois de adicionar a parte Xaml.
Patrick Quirk
Muito bom, funcionou como esperado. Gosto disso porque me ajuda a manter as preocupações do View separadas ao fazer o MVVM.
Killnine
16

Aqui está uma solução muito boa e muito simples no MSDN :

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

Aqui está o código por trás:

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();
        }
    }
}
BillBR
fonte
1
Essencialmente, esta é a mesma solução que a mais classificada neste segmento. Mas, uma vez que dois anos antes, agora eu sei de onde @Donnelle emprestado;)
Sergey Aldoukhov
Essa solução parecia a mais fácil e funcionou para mim. Eu queria um subconjunto específico de texto selecionado por padrão ao entrar na caixa de texto.
Jack B Nimble
10

Eu acho que isso funciona bem:

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

Se você deseja implementá-lo como um método de extensão:

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

E no seu GotFocusevento:

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

Eu descobri a solução acima porque, há vários meses, eu estava procurando uma maneira de definir o foco para um dado UIElement. Descobri o código abaixo em algum lugar (crédito é dado por aqui) e funciona bem. Eu o publico mesmo que não esteja diretamente relacionado à pergunta do OP, pois demonstra o mesmo padrão de uso Dispatcherpara trabalhar com 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);
}
Sam
fonte
Eu acho que esse é o método mais simples de implementar. Depois de criar o método de extensão, basta chamar myTextBox.SelectAllText (). Por que esta resposta não recebeu mais pontos? por que as outras soluções são muito melhores?
Tono Nam
2
Eu evitaria esse método porque ele depende de uma chamada assíncrona para executar após o manipulador MouseUp da caixa de texto. Eu não confiaria que isso fosse 100% determinístico e pode levar a um comportamento inconsistente. Mesmo que isso seja improvável, prefiro seguir os métodos infalíveis acima.
Rob H
6

Aqui está uma tentativa de resolver alguns dos problemas com outras soluções:

  1. O uso do botão direito do mouse no menu de contexto para recortar / copiar / colar seleciona todo o texto, mesmo que você não tenha selecionado tudo.
  2. Ao retornar do menu de contexto do botão direito, todo o texto é sempre selecionado.
  3. Ao retornar ao aplicativo com Alt+ Tab, todo o texto é sempre selecionado.
  4. Ao tentar selecionar apenas parte do texto no primeiro clique, tudo sempre é selecionado (ao contrário da barra de endereço do Google Chrome, por exemplo).

O código que escrevi é configurável. Você pode escolher em quais ações o seleccionar todo comportamento deve ocorrer, definindo três campos somente leitura: SelectOnKeybourdFocus, SelectOnMouseLeftClick, SelectOnMouseRightClick.

A desvantagem desta solução é que ela é mais complexa e o estado estático é armazenado. Parece uma luta feia com o comportamento padrão do TextBoxcontrole. Ainda assim, ele funciona e todo o código está oculto na classe de contêiner 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;
    }
}

Para anexar a propriedade anexada a a TextBox, tudo o que você precisa fazer é adicionar o namespace xml ( xmlns) da propriedade anexada e usá-lo da seguinte maneira:

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

Algumas notas sobre esta solução:

  1. Para substituir o comportamento padrão de um evento de mouse para baixo e ativar a seleção de apenas parte do texto no primeiro clique, todo o texto é selecionado no evento de mouse para cima.
  2. Eu tive que lidar com o fato de que o se TextBoxlembra de sua seleção depois que perde o foco. Na verdade, eu substituí esse comportamento.
  3. Eu tinha que lembrar se um botão do mouse pressionado é a primeira ação no TextBox( FirstActionIsMouseDowncampo estático).
  4. Eu tive que lembrar o menu de contexto aberto com um clique direito ( ContextMenucampo estático).

O único efeito colateral que encontrei é quando SelectOnMouseRightClické verdade. Às vezes, o menu de contexto do botão direito pisca quando é aberto e clicar com o botão direito do mouse em um espaço em branco no campo TextBox"não selecionar tudo".

Eliahu Aaron
fonte
5

Descobri que nenhuma das respostas aqui apresentadas imita uma caixa de texto padrão do Windows. Por exemplo, tente clicar no espaço em branco entre o último caractere da caixa de texto e o lado direito da caixa de texto. A maioria das soluções aqui sempre seleciona todo o conteúdo, o que dificulta a adição de texto a uma caixa de texto.

A resposta que apresento aqui se comporta melhor a esse respeito. É um comportamento (portanto, requer o assembly System.Windows.Interactivity do SDK do Blend ). Também pode ser reescrito usando as propriedades anexadas.

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

Isso é baseado no código que encontrei aqui .

Kristof Verbiest
fonte
1
Embora essa seja uma boa resposta, acho que quando o usuário clica no espaço em branco, sua intenção (em um aplicativo de negócios) provavelmente substitui todo o valor, portanto, selecionar tudo é a abordagem correta.
Sergey Aldoukhov 27/07/2010
1
Sergey: o primeiro clique selecionará o valor inteiro, o segundo clique colocará o cursor à direita do valor. Nas outras soluções apresentadas, o segundo clique manterá todo o valor selecionado, dificultando a anexação ao valor.
Kristof Verbiest
Como isso é usado? Adicionei esse código ao App.xaml.cs, mas ele não pareceu afetar os TextBoxes no meu aplicativo.
PIntag
5

Esta implementação simples funciona perfeitamente para mim:

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

Para aplicá-lo a todos TextBox, coloque o seguinte código apósInitializeComponent();

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

No arquivo App.xaml:

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

No arquivo App.xaml.cs:

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

Com esse código, você alcança tudo TextBoxem seu aplicativo.

Darshan Faldu
fonte
3

Retirado daqui :

Registre o manipulador de eventos global no arquivo App.xaml.cs:

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

    base.OnStartup(e);
}

Em seguida, o manipulador é tão simples quanto:

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

Sei que isso é muito antigo, mas aqui está minha solução, baseada nos espaços de nomes expressões / interatividade e interatividade da Microsoft.

Primeiro, segui as instruções neste link para colocar os gatilhos de interatividade em um estilo.

Então tudo se resume a isso

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

e isto

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

No meu caso, eu tenho um controle de usuário onde estão as caixas de texto que possuem um code-behind. O code-behind tem a função de manipulador. Dei ao meu controle de usuário um nome em XAML e estou usando esse nome para o elemento. Isso está funcionando perfeitamente para mim. Simplesmente aplique o estilo a qualquer TextBoxlugar em que você gostaria que todo o texto fosse selecionado ao clicar noTextBox .

O primeiro CallMethodActionchama o SelectAllmétodo da caixa de texto quando o GotKeyboardFocusevento é TextBoxacionado.

Eu espero que isso ajude.

wiyosaya
fonte
Como essas perguntas são antigas, pode ajudar sua resposta a receber alguma atenção se você mencionar por que alguém pode escolher essa abordagem.
divibisan
Primeiro, isso não precisa ser colocado em um estilo, mas acho óbvio que existem muitos controles de caixa de texto que precisam disso; um estilo é o caminho a percorrer.
wiyosaya
1
Talvez alguns não concordem com essa abordagem, no entanto, por que você pode usar essa abordagem, ela não requer subclassificação de TextBox, registrando eventos do manipulador de classes, métodos de extensão, criando propriedades anexadas etc. Como estilo, também pode ser adicionado para o dicionário de recursos de qualquer projeto xaml. Sem a chave x:, ela seria aplicada a qualquer instância TextBox dentro do escopo do dicionário de recursos sem precisar alterar o xaml de cada caixa de texto individual. Em alguns casos, pode ser uma abordagem mais limpa.
wiyosaya
2

Eu usei a resposta de Nils, mas converti para mais flexível.

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

No XAML, você pode usar como um destes:

<!-- 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" />
bafsar
fonte
1
Solução realmente boa para uso em modelos, já que você pode vinculá-lo ao xaml sem qualquer código real, apenas um comportamento estendido da caixa de texto.
Eric Johansson
2

Aqui está a versão em C # da resposta postada por @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);
}

considerando que MyTextBox_GotFocuso manipulador de eventos é atribuído ao GotFocusevento de MyTextBox.

ViRuSTriNiTy
fonte
2

Eu tenho uma resposta um pouco simplificada para isso (com apenas o PreviewMouseLeftButtonDownevento) que parece imitar a funcionalidade usual de um navegador:

No XAML, você tem a TextBoxdizer:

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

Em 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();
    }
}
Danield
fonte
1
Talvez você queira adicionar um evento GotKeyboardFocus com TextBox.SelectAll () dentro para pessoas que navegam pelo aplicativo. Sua solução também funciona para PasswordBoxes (como os PasswordBoxes são do tipo selado, não podem ser estendidos).
David Sherret 29/06
1

Tente este método de extensão para adicionar o comportamento desejado a qualquer controle TextBox. Ainda não o testei extensivamente, mas parece atender às minhas necessidades.

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();
            }
        }
    }
}
David Kirkland
fonte
1

Pesquisei bastante a solução, encontrei algumas soluções para selecionar todas. Mas, o problema é quando clicamos com o botão direito do mouse e recortamos / copiamos depois de selecionar parte do texto da caixa de texto, ela seleciona todas as partes que selecionei. Para corrigir isso aqui é a solução. Basta adicionar o código abaixo no evento de seleção do teclado. Isso funcionou para mim.

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();
}
Sambu Praveen
fonte
1

Eu tive o mesmo problema. No VB.Net, é fácil assim:

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 # (graças a 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);
}
Nasenbaer
fonte
Melhor solução para mim, eu postei uma tradução C # aqui: stackoverflow.com/a/48385409/3936440
ViRuSTriNiTy
Para mim, essa abordagem ocasionalmente falha ao selecionar texto. Eu acho que é condição de corrida devido ao BeginInvoke.
Vimes
Por favor especifique. A prioridade do expedidor está trabalhando em aplicativos padrão conforme o esperado. Qual é a sua situação? Você tentou exatamente como descrito? Algo especial na sua solução?
Nasenbaer 6/06
1

Esta é de longe a solução mais simples.

Adicione um manipulador global ao aplicativo (App.xaml.cs) e pronto. Você precisará de apenas algumas linhas de código.

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

    base.OnStartup(e);
}

Portanto, use a classe EventManager para registrar um manipulador de eventos global em um tipo (TextBox). O manipulador real é simples:

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

Verifique aqui: WPF TextBox SelectAll on Focus

Espero que ajude.

Marlon Assef
fonte
1

Para aqueles interessados ​​na abordagem de Donnelle / Groky, mas deseja um clique à direita do último caractere (mas ainda dentro do TextBox) para colocar o sinal de intercalação no final do texto inserido, eu vim com esta solução:

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

O GetRoundedCharacterIndexFromPointmétodo foi retirado deste post.

PIntag
fonte
1
Funciona bem, mas o evento de clique duplo não é acionado #
Rodrigo Caballero /
Na verdade, ele entra no evento de duplo clique, mas a propriedade OriginalSource é do tipo TextBoxView. Portanto, o método SelectAllText deve ser assim: private static void SelectAllText (remetente do objeto, RoutedEventArgs e) {var textBox = e.OriginalSource as TextBox; if (textBox! = null) {textBox.SelectAll (); System.Diagnostics.Debug.WriteLine ("Selected ALL"); } else if (remetente é TextBox) {(remetente como TextBox) .SelectAll (); }
Rodrigo Caballero
1

Após pesquisar e testar, encontrei uma solução simples que funcionou para mim.

Você precisa adicionar um manipulador de Loadedeventos ao evento da janela do seu contêiner:

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

Em seguida, você deve criar o manipulador para o referenciado RoutedEventHandlerno código anterior:

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

Agora, você pode adicionar o SelectAll()comando nos GotFocusmanipuladores de eventos a qualquer TextBoxcontrole separadamente:

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

Seu texto agora está selecionado em foco!

Adaptado da solução Dr. WPF, fóruns do MSDN

DonBeto97
fonte
Acabei de usar: private async void TBTime_GotFocus (remetente do objeto, RoutedEventArgs e) {TextBox tb = (TextBox) e.OriginalSource; aguarde Dispatcher.RunAsync (Windows.UI.Core.CoreDispatcherPriority.Normal, async () => {tb.SelectAll ();}); }
David Jones
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
Brian
fonte
Se você tiver 20 caixas de texto em uma janela, criará três métodos para cada caixa de texto? Essa abordagem não é boa. Dê uma olhada aqui: rachel53461.wordpress.com/2011/11/05/…
Alexandru Dicu
0

Isso parece funcionar bem para mim. É basicamente uma recapitulação de algumas postagens anteriores. Acabei de colocar isso no meu arquivo MainWindow.xaml.cs no construtor. Crio dois manipuladores, um para teclado e outro para o mouse, e canalizo os dois eventos para a mesma função, HandleGotFocusEventdefinida imediatamente após o construtor no mesmo arquivo.

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();
}
Ted
fonte
Fácil e fácil, mas parece ter um problema de temporização - a cada duas tentativas (clique do mouse), a seleção é desmarcada imediatamente imediatamente ...?
T4NK3R 18/09/16
0

Uma maneira fácil de substituir o mouseDown e selecionar tudo após o clique duplo é:

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

Tente colocar isso no construtor de qualquer controle que esteja abrigando sua caixa de texto:

Loaded += (sender, e) =>
{
    MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
    myTextBox.SelectAll();
}
CodeOtaku
fonte
Essa abordagem não funciona quando você coloca isso em um construtor de janelas.
ViRuSTriNiY
0

Se houver um evento que cancele a seleção de texto durante o OnFocusmouse, normalmente atraso a seleção de todos.

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

Eu testei todos eles, mas apenas o seguinte deu certo:

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();
}
Ehsan Zargar Ershadi
fonte
4
Isso também é um uso obsceno e obsceno de códigos de hash. Eu li isso, link
RichK
3
E usando GetType().Nameem vez de isou asé bastante hacky
RichK
-1

Vejo que há muitas respostas, mas como a aprovada, os métodos que devem ser usados ​​são EditTextBoxGotCapture

com o seguinte código por trás:

private void EditTextBoxGotCapture(object sender, MouseEventArgs e)
{
    if (sender is TextBox tb)
    {
        tb.Select(0, tb.Text.Length);
    }
}
Liviu Sosu
fonte