AutoSelect em controles TextBox do WPF/Silverlight

Como é sabido, o controle TextBox no WPF ou Silverlght ao receberem foco vindo do teclado não selecionam automaticamente seu conteúdo. Esse é um comportamento esperado, já que estamos acostumados com o TextBox do Windows Form ou TEdit do Delphi (para os Delpheiros).

É fácil criar essa implementação. O modo mais “RAD” ao meu ver é sobrescrever o evento GotKeyboardFocus de uma maneira global, que atingisse todos os controles TextBox da aplicação.

Isso pode ser feito dentro do arquivo App.xaml.cs. Essa classe representa a aplicação em si, contendo vários eventos que podem ser sobrecarregador por nós. Para alcançarmos o objetivo, o evento OnStartup deve ser sobrecarregado. Esse evento é disparado quando a aplicação é iniciada.

Assim, nele podemos codificar algo que deve acontecer no momento da carga da aplicação, esse algo será a determinação que todo evento GodKeyboardFocus que for disparado por controles TextBox será implementado por um método nosso. Isso é feito assim:

protected override void OnStartup(StartupEventArgs e)
{
   EventManager.RegisterClassHandler(typeof(TextBox),
                   TextBox.GotKeyboardFocusEvent,
                   new RoutedEventHandler(TextBox_SelecionarConteudo));
   base.OnStartup(e);  
}

private void TextBox_SelecionarConteudo(object sender, RoutedEventArgs e)
{
   var textbox = sender as TextBox;
   textbox.SelectAll();
}

Beleza isso vai funcionar, é uma solução eficaz. Mas, qual o principal problema dessa abordagem? Reutilização. Esse não é um código reutilizável. Se for necessário ter isso em um outro projeto seu, você terá que fazer a mesma coisa. Por isso eu disse que ele é eficaz e não eficiente. A eficácia é resolver o problema sem pensar muito nas consequências, a eficiência é resolver um problema da melhor forma. Infelizmente o desenvolvimento RAD acaba conduzindo a algo muito eficaz… mas isso é assunto pra outra conversa….

Behaviors

A tradução de behavior é comportamento. Para um textbox selecionar o conteúdo ao receber o foco vindo do teclado é uma questão de comportamento, que ele não traz consigo. Existe uma técnica que permite a criação desse comportamentos, de forma reutilizável.

Ela faz uso de AttachedProperties, que não um novo tipo de propriedade trazida com o WFP e Silverlight. Ela permite adicionar, anexar, novas propriedades a objetos já existentes. Assim, vamos criar uma nova propriedade “AutoSelect” que quando for true, irá fazer o TextBox se comportar como queremos. O legal dessa abordagem é a possibilidade de se ter uma biblioteca de behaviors, que podem ser então compartilhados, ou seja, reutilizados.

Em uma nova classe codificamos o seguinte:

public class AutoSelectAttachedProperty
{
    public static bool GetAutoSelect(DependencyObject obj)
    {
        return (bool)obj.GetValue(AutoSelectProperty);
    }

    public static void SetAutoSelect(DependencyObject obj, bool value)
    {
        obj.SetValue(AutoSelectProperty, value);
    }

    public static readonly DependencyProperty AutoSelectProperty =
        DependencyProperty.RegisterAttached(“AutoSelect”, typeof(bool), typeof(AutoSelectAttachedProperty),
                                            new FrameworkPropertyMetadata(false,
                                                                          new PropertyChangedCallback(
                                                                              OnAutoSelectChanged)));

    private static void OnAutoSelectChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        TextBox textBox = null;

        try
        {
            textBox = (TextBox) d;
        }
        catch
        {

                    return;

        }

        if (textBox != null)
        {
            if ((bool)e.NewValue)
            {
                textBox.GotKeyboardFocus += delegate { textBox.SelectAll(); };
            }
            return;
        }

    }
}

Não vou entrar em muito detalhe desse código não, quem se interessar pede aí nos comentários que explico com detalhes…

Agora pra aplicar, é possível usar um estilo implícito para TextBox, e automaticamente todos terão o comportamento:

<Style TargetType=”{x:Type TextBox}”>
        <Setter Property=”KeyboardNavigation.TabNavigation” Value=”None”/>
        <Setter Property=”FocusVisualStyle” Value=”{x:Null}”/>
        <Setter Property=”Validation.ErrorTemplate” Value=”{x:Null}”/>
        <Setter Property=”Margin” Value=”3,0,5,0″/>
        <Setter Property=”UndoLimit” Value=”1″/>
        <Setter Property=”FontFamily” Value=”Tahoma”/>
        <Setter Property=”Util:AutoSelectAttachedProperty.AutoSelect” Value=”true”/>
</Style>

E pronto!

Esse post foi publicado em WPF. Bookmark o link permanente.

Uma resposta para AutoSelect em controles TextBox do WPF/Silverlight

  1. Diego Ramos disse:

    Mto bom cara.. ta aí uma parada q eu curti!! mto obrigado

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s