sábado, 2 de marzo de 2013

Seleccionar el texto al obtener el foco (Select All - Click Fix)

Seleccionar el texto al obtener el foco

Objetivos

1) Seleccionar todo el texto de una caja de texto cuando la misma obtiene el foco
2) Eliminar el error que se nos puede presentar cuando queremos hacerlo de forma intuitiva.

La forma natural de hacerlo

En un proyecto en blanco ponemos varias cajas de texto (TextBox1, TextBox2, TextBox3, ...). Escribir algo en la propiedad Text de cada una de ellas.

Programar el TextBox1:

    Private Sub TextBox1_Enter(sender As Object, e As EventArgs) Handles TextBox1.Enter
        Dim sdr As TextBox = sender
        sdr.SelectAll()
    End Sub

Podremos notar como cuando se presiona la tecla tabulador, el TextBox1 se comporta distinto al resto.

Problema:

Este método tiene un pequeño inconveniente: si en lugar de hacer foco con la tecla tabulador, se hace con el clic del mouse, entonces SelectAll no funciona.

Otra mejor forma de seleccionar el texto que funciona incluso con el click

Porque ocurre? El evento Enter se dispara antes que los eventos del mouse (Click por ejemplo).
El TextBox obtiene el foco, entonces se selecciona todo el texto (por el SelectAll que pusimos)
Luego visual se encarga de poner el cursor en el lugar que el usuario hizo el click por lo que automáticamente el SelectAll anteriormente ejecutado queda sin efecto.

La solución:

Crear los siguientes procedimientos:

#Region "TextBox Events..."

    Private Sub TextBox_Enter(sender As Object, e As EventArgs) Handles TextBox1.Enter
        Dim sdr As TextBox = sender
        If (MouseButtons = Windows.Forms.MouseButtons.Left) Then
            AddHandler sdr.MouseDown, AddressOf TextBox_MouseUp
        Else
            TextBox_MouseUp(sdr, New EventArgs)
        End If
    End Sub

    Private Sub TextBox_MouseUp(sender As Object, e As EventArgs)
        Dim sdr As TextBox = sender
        sdr.SelectAll()
        RemoveHandler sdr.MouseDown, AddressOf TextBox_MouseUp
    End Sub

#End Region

    Public Sub OnFocusSelectAll(tb As TextBox, Optional value As Boolean = True)
        RemoveHandler tb.Enter, AddressOf TextBox_Enter
        AddHandler tb.Enter, AddressOf TextBox_Enter
    End Sub

La explicación de lo que se hace es la siguiente, cuando el TextBox obtiene el foco compruebo si es por el efecto del mouse (es decir el clic)
De ser así programo el TextBox para que cuando se suelte el botón del mouse se ejecute el SelectAll.
En caso contrario Ejecuto SelectAll normalmente

Luego en el load del formulario lo siguiente:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OnFocusSelectAll(TextBox1)
        OnFocusSelectAll(TextBox2)
        OnFocusSelectAll(TextBox3)
        OnFocusSelectAll(TextBox4)
    End Sub






3 comentarios:

  1. Muy buena rutina... funciona perfectamente y es ideal para incorporarla fácilmente a tu programa. Muchas gracias al autor.

    ResponderEliminar
  2. Muchas gracias! Funcionó perfecto. Seguí con el blog que serás de mucha ayuda!

    ResponderEliminar
  3. Funciono al 100%, habia creado mi propio textbox (con propiedades tipo de caja: texto, numero, fecha, y otras propiedades mas), y para que seleccionar el texto tenia un timer y tenia ciertas fallas, con esto quedo de lujo! Saludos!

    ResponderEliminar