Índice de la sección dedicada a .NET (en el Guille) - Migrar de VB6 a .NET

Algunas acciones comunes con las cajas de textos


Publicado el 27/Dic/2002
Actualizado el 03/Jun/2006


Algunas acciones comunes con las cajas de textos:


Cambiar al siguiente control al pulsar Intro en una caja de textos (03/Jun/06)

Como ya ocurría con VB6, podemos usar SendKeys para enviar una pulsación de la tecla TAB cuando detectemos que se ha pulsado la tecla Intro (o Enter).
Esa comprobación la haremos en el evento KeyPress de cada caja de textos, pero no es necesario que escribamos el mismo código en todas las cajas de textos en las que queramos esta funcionalidad, ya que en Visual Basic para .NET (y también en C#) se pueden asociar el mismo método o procedimiento para interceptar el evento de varios controles (siempre que sean compatibles los parámetros de esos eventos).

Nota:
Lo que debes tener en cuenta es que esto lo que hará será "simular" la pulsación de la tecla TAB, por tanto si hay otros controles "en medio", el que recibirá el foco después de pulsar INTRO en esa caja de textos será el siguiente control que haya, no la siguiente caja de textos.

 

En VB6: Lo tendremos que hacer en cada una de las cajas de texto en la que queramos esa funcionalidad

If KeyAscii = vbKeyReturn Then
    KeyAscii = 0
    SendKeys "{TAB}"
End If

 

En VB.NET: Podemos asociar varios controles al mismo método de evento:

If e.KeyChar = ChrW(Keys.Enter) Then
    e.Handled = True
    SendKeys.Send("{TAB}")
End If

 

En C#: Es como en VB, pero con punto y coma al final, je, je.

if( e.KeyChar == (char)Keys.Enter )
{
    e.Handled = true;
    SendKeys.Send("{TAB}");
}

 


Seleccionar todo el código al recibir el foco (27/Dic/02)

En Visual Basic clásico, cuando un TextBox recibe el foco, se suele usar algo como esto:

En el evento GotFocus del TextBox, hay que escribir:

Private Sub Text1_GotFocus()
    ' seleccionar el texto al recibir el foco
    With Text1
        .SelStart = 0
        .SelLength = Len(.Text)
    End With
End Sub

 

En Visual Basic .NET es tan simple, que se hace con una sola instrucción:

Private Sub TextBox1_Enter(ByVal sender As Object, _
                           ByVal e As System.EventArgs) _
                           Handles TextBox1.Enter
    ' seleccionar el texto al recibir el foco
    TextBox1.SelectAll()
End Sub

 

En C# también se hace con una sola instrucción, pero al estilo C:

private void textBox1_Enter(object sender, 
                            System.EventArgs e)
{
    textBox1.SelectAll();
}

 

Nota:
En Visual Studio .NET 2002 aunque existe el evento GotFocus, éste no se muestra en la lista de eventos disponibles, pero se puede usar el evento Enter, que si se muestra.
En la versión 2003, en VB se muestran los dos eventos, pero en C# sólo Enter.
De todas formas, te aclararé que primero se produce el evento Enter y después el GotFocus.
Según la documentación de VS .NET: Los eventos GotFocus y LostFocus son eventos de bajo nivel asociados a los mensajes de Windows WM_SETFOCUS y WM_KILLFOCUS. También recomienda que se usen los eventos Enter y Leave.


Evitar el pitido al pulsar Intro (y evitar que se interprete la tecla) (27/Dic/02)

En VB6, cuando interceptamos la tecla Intro, porque queramos hacer cualquier cosa cuando se pulsa en una caja de textos, solemos asignar un valor cero al parámetro recibido en el evento (KeyAscii), ese cero le indica al runtime que no tenga en cuenta la pulsación de la tecla.

Private Sub Text1_KeyPress(KeyAscii As Integer)
    ' si se pulsa Intro, asignar cero para ignorar la pulsación
    If KeyAscii = vbKeyReturn Then
        ' con esto hacemos que se ignore la pulsación
        KeyAscii = 0
        '... el código ...
        ' (por ejemplo pasar a otro control)
        Text2.SetFocus
    End If
End Sub

 

En VB.NET no existe el parámetro KeyAscii, en su lugar hay un parámetro de evento entre cuyos miembros está la propiedad KeyChar que representa a la tecla pulsada, pero esta propiedad es de solo lectura, por tanto no se puede asignar ningún valor. Pero, al menos para el caso que estamos tratando en este punto, eso no supone ningún inconveniente, ya que hay una propiedad que nos viene como anillo al dedo: Handled, si le asignamos un valor True a esta propiedad, la pulsación de la tecla será ignorada.

Private Sub TextBox1_KeyPress(ByVal sender As Object, _
                              ByVal e As System.Windows.Forms.KeyPressEventArgs) _
                              Handles TextBox1.KeyPress
    ' si la tecla pulsada es la tecla Intro
    If e.KeyChar = Convert.ToChar(Keys.Return) Then
        ' con esto hacemos que se ignore la pulsación
        e.Handled = True
        '... el código ...
        ' (por ejemplo pasar a otro control)
        TextBox2.Focus()
    End If
End Sub

 

En C# sería como en VB.NET, pero tratando los caracteres al estilo C:

private void textBox1_KeyPress(object sender, 
                               System.Windows.Forms.KeyPressEventArgs e)
{
    // si la tecla pulsada es la tecla Intro
    if (e.KeyChar == (char)13)
    {
        // con esto hacemos que se ignore la pulsación
        e.Handled = true;
        // ... el código ... 
        // (por ejemplo pasar a otro control)
        textBox2.Focus();
    }
}

 


Cambiar una tecla pulsada por otra diferente (27/Dic/02)

En VB6: Como he mencionado antes, en VB.NET el parámetro que indica la tecla pulsada en el evento KeyPress, es de solo lectura, por tanto, algo que en VB6 es, (en esta ocasión), tan simple como esto:

Private Sub Text1_KeyPress(KeyAscii As Integer)
    ' cambiar el punto por la coma
    If KeyAscii = Asc(".") Then
        KeyAscii = Asc(",")
    End If
End Sub

 

En VB.NET hay que utilizar SendKeys, algunos pensarán que es una mala opción, sobre todo si han tenido problemas en VB6 con SendKeys, la única "esperanza" que nos queda es pensar que ahora SendKeys funcionará bien (o mejor), ya que es una clase del .NET Framework, la cual también se puede usar con C#.
El código equivalente al mostrado anteriormente sería:

Private Sub TextBox1_KeyPress(ByVal sender As Object, _
                              ByVal e As System.Windows.Forms.KeyPressEventArgs) _
                              Handles TextBox1.KeyPress
    ' cambiar el punto por la coma
    If e.KeyChar = "."c Then
        ' si no ignoramos esta pulsación, tendremos dos
        e.Handled = True
        ' enviar la nueva tecla
        SendKeys.Send(",")
    End If
End Sub

Te aclaro un poco lo que se hace:
Para saber si es el punto, usamos "."c que sería el equivalente a Asc(".") es decir convertir un String en un Char.
El e.Handled = True es para evitar que se envíe la pulsación del punto al TextBox.
El SendKets.Send(",") envía la pulsación de la coma (o cualquier otra cadena) al control que tiene el foco.

 

En C# sería muy parecido a VB.NET (esto no lo voy a repetir más, ya que, salvo por la sintaxis del lenguaje, tanto en VB.NET como en C# se hace de la misma forma)

private void textBox1_KeyPress(object sender, 
                               System.Windows.Forms.KeyPressEventArgs e)
{
    // cambiar el punto por la coma
    if (e.KeyChar == '.')
    {
        // si no ignoramos esta pulsación, tendremos dos
        e.Handled = true;
        // enviar la nueva tecla
        SendKeys.Send(",");
    }
}

Seleccionar una parte del texto (27/Dic/02)

Este caso es muy parecido en ambas versiones de Visual Basic, ya que se utilizan las mismas instrucciones. Pero aún así, veamos el código en cada versión (y también en C#)
Para que el efecto sea visible, debemos asignar un valor False a la propiedad HideSelection del TextBox (en ambas versiones existe esa propiedad y lo que hace es que cuando el TextBox no tiene el foco se sigue mostrando la selección actual)
Con el siguiente código seleccionamos desde la 2ª posición, 3 caracteres. Si el contenido del TextBox fuese TextBox1, se seleccionaría ext.

En VB6:

Private Sub seleccionarCmd_Click()
    Text1.SelStart = 1   ' realmente es la 2ª posición
    Text1.SelLength = 3  ' seleccionamos tres caracteres
End Sub

 

En VB.NET:

Private Sub seleccionarBtn_Click(ByVal sender As Object, _
                                 ByVal e As System.EventArgs) _
                                 Handles seleccionarBtn.Click
    TextBox1.SelectionStart = 1     ' realmente es la 2ª posición
    TextBox1.SelectionLength = 3    ' seleccionamos 3 caracteres
End Sub

 

En C#:

private void seleccionarBtn_Click(object sender,
                                  System.EventArgs e)
{
    textBox1.SelectionStart = 1;    // realmente es la 2ª posición
    textBox1.SelectionLength = 3;   // seleccionamos 3 caracteres
}

 


Copiar el texto seleccionado en el ClipBoard (27/Dic/02)

Para copiar texto de un TextBox en el portapapeles, en VB6 tenemos que usar el objeto Clipboard para realizar esa acción (o usar el API de Windows), en .NET las cajas de textos tienen un método que permite realizar esa acción sin necesidad de usar el portapapeles.

En estos ejemplos, si hay texto seleccionado, se copiará sólo la selección, si no hay selección previa, se copiará todo el contenido.

En VB6:

Private Sub copiarCmd_Click()
    ' copiar la selección en el Clipboard
    If Text1.SelLength > 0 Then
        Clipboard.SetText Text1.SelText
    Else
        ' copiar todo el texto
        Clipboard.SetText Text1.Text
    End If
End Sub

 

En VB.NET:

Private Sub copiarBtn_Click(ByVal sender As Object, _
                            ByVal e As System.EventArgs) _
                            Handles copiarBtn.Click
    If TextBox1.SelectionLength = 0 Then
        ' en .NET copia la selección actual
        ' por tanto, si no hay selección, lo seleccionamos todo
        TextBox1.SelectAll()
    End If
    ' copiamos la selección en el portapapeles
    TextBox1.Copy()
End Sub

 

En C#:

private void copiarBtn_Click(object sender, System.EventArgs e)
{
    if (textBox1.SelectionLength == 0)
    {
        // en .NET copia la selección actual
        // por tanto, si no hay selección, lo seleccionamos todo
        textBox1.SelectAll();
    }
    // copiamos la selección en el portapapeles
    textBox1.Copy();
}

 


Cortar el texto seleccionado (y dejarlo en el ClipBoard) (27/Dic/02)

La operación de cortar es la misma que la de copiar, además de eliminar el texto.
En VB6, nuevamente, tenemos que usar el objeto Clipboard, en .NET también existe un método para realizar esa operación.

En estos ejemplos, sólo se cortará si hay texto seleccionado.

En VB6:

Private Sub cortarCmd_Click()
    ' copiar la selección en el Clipboard
    If Text1.SelLength > 0 Then
        Clipboard.SetText Text1.SelText
        ' eliminar la selección
        Text1.SelText = ""
    End If
End Sub

 

En VB.NET:

Private Sub cortarBtn_Click(ByVal sender As Object, _
                            ByVal e As System.EventArgs) _
                            Handles cortarBtn.Click
    ' si hay texto seleccionado
    If TextBox1.SelectionLength > 0 Then
        ' cortarlo
        TextBox1.Cut()
    End If
End Sub

 

En C#:

private void cortarBtn_Click(object sender, System.EventArgs e)
{
    // si hay texto seleccionado
    if (textBox1.SelectionLength > 0)
    {
        // cortarlo
        textBox1.Cut();
    }
}

 


Pegar el texto del portapapeles (Clipboard) (27/Dic/02)

Al igual que ocurría con la copia de texto en el portapapeles, para pegar del portapapeles al TextBox en .NET se puede hacer con un llamada al método Paste, mientras que con VB6, hay que seguir usando el objeto Clipboard.

En estos ejemplos, si hay texto seleccionado, se sustituirá por lo que haya en el portapapeles, sino, se pegará sustituyendo todo el texto.

En VB6:

Private Sub pegarCmd_Click()
    ' pegar en el textbox lo que haya en el clipboard
    ' si hay alguna selección sustituirlo
    If Text1.SelLength > 0 Then
        Text1.SelText = Clipboard.GetText
    Else
        Text1.Text = Clipboard.GetText
    End If
End Sub

 

En VB.NET:

Private Sub PegarBtn_Click(ByVal sender As Object, _
                           ByVal e As System.EventArgs) _
                           Handles PegarBtn.Click
    ' pegar en el textbox lo que haya en el clipboard
    ' si hay alguna selección sustituirlo
    If TextBox1.SelectionLength = 0 Then
        ' si no hay selección, se sustituirá lo que había
        TextBox1.SelectAll()
    End If
    TextBox1.Paste()
End Sub

 

En C#:

private void PegarBtn_Click(object sender, System.EventArgs e)
{
    // pegar en el textbox lo que haya en el clipboard
    // si hay alguna selección sustituirlo
    if (textBox1.SelectionLength == 0)
    {
        // si no hay selección, se sustituirá lo que había
        textBox1.SelectAll();
    }
    textBox1.Paste();
}

 


Saber si se puede deshacer (27/Dic/02)

En VB6, para saber si se puede deshacer lo escrito en un TextBox, hay que utilizar el API de Windows, sin embargo en .NET simplemente se pregunta a una propiedad que ahora incluyen las cajas de texto y se sabe si se puede o no deshacer.

En VB6:
Para saber si se puede deshacer, hay que usar la función SendMessage del API de Windows, la declaración sería la siguiente, esta declaración hay que ponerla en la parte de declaraciones (General) del formulario.

Private Declare Function SendMessage Lib "User32" Alias "SendMessageA" _
    (ByVal hWnd As Long, ByVal wMsg As Long, _
     ByVal wParam As Long, ByVal lParam As Long) As Long

 

Private Sub canUndoCmd_Click()
    ' saber si se puede deshacer
    Const EM_CANUNDO As Long = &HC6
    '
    If SendMessage(Text1.hWnd, EM_CANUNDO, 0&, 0&) Then
        Label1 = "Se puede deshacer"
    Else
        Label1 = "NO se puede deshacer"
    End If
End Sub

 

En VB.NET:

Private Sub canUndoBtn_Click(ByVal sender As Object, _
                             ByVal e As System.EventArgs) _
                             Handles canUndoBtn.Click
    If TextBox1.CanUndo Then
        Label1.Text = "Se puede deshacer"
    Else
        Label1.Text = "NO se puede deshacer"
    End If
End Sub

 

En C#:

private void canUndoBtn_Click(object sender, System.EventArgs e)
{
    if (textBox1.CanUndo)
    {
        label1.Text = "Se puede deshacer";
    }
    else
    {
        label1.Text = "NO se puede deshacer";
    }       
}

 


Deshacer la última modificación (27/Dic/02)

Para poder deshacer los últimos cambios realizados en un TextBox, con VB6 hay que usar el API de Windows, pero con .NET simplemente se llama a un método.

En VB6:
La función del API usada para la operación deshacer es la misma que la mostrada en el punto anterior.

El problema con VB6 es que para poder deshacer, hay que utilizar también el API de Windows para realizar las acciones de cortar y borrar, si no se hace así, no podremos deshacer.

Aquí te muestro las operaciones de Copiar, Cortar,  Pegar y Seleccionar todo usando el API de Windows. Si usas el API no deberías usar el método normal, ya que no son compatibles.

Copiar usando API

' copiar lo seleccionado, usando el API
Const WM_COPY As Long = &H301
Const EM_SETSEL As Long = &HB1
'
' si no hay selección, seleccionarlo todo
If Text1.SelLength = 0 Then
    SendMessage Text1.hWnd, EM_SETSEL, 0&, -1&
End If
SendMessage Text1.hWnd, WM_COPY, 0&, 0&

 

Cortar usando API

' cortar el texto seleccionado, usando API
' sólo, si hay algo seleccionado...
Const WM_CUT As Long = &H300

SendMessage Text1.hWnd, WM_CUT, 0&, 0&

 

Pegar usando API

' pegar usando el API
Const WM_PASTE As Long = &H302
'
SendMessage Text1.hWnd, WM_PASTE, 0&, 0&

 

Seleccionar todo usando API

Const EM_SETSEL As Long = &HB1
'
' seleccionarlo todo
SendMessage Text1.hWnd, EM_SETSEL, 0&, -1&

 

Deshacer

Private Sub deshacerCmd_Click()
    Const EM_CANUNDO As Long = &HC6
    Const EM_UNDO As Long = &HC7
    '
    ' se comprueba si se puede deshacer
    If SendMessage(Text1.hWnd, EM_CANUNDO, 0&, 0&) Then
        ' si es así, se deshace
        SendMessage Text1.hWnd, EM_UNDO, 0&, 0&
    End If
End Sub

 

En VB.NET:

Private Sub deshacerBtn_Click(ByVal sender As Object, _
                              ByVal e As System.EventArgs) _
                              Handles deshacerBtn.Click
    ' si se puede deshacer
    If TextBox1.CanUndo Then
        ' deshacer
        TextBox1.Undo()
    End If
End Sub

 

En C#:

private void deshacerBtn_Click(object sender, System.EventArgs e)
{
    // si se puede deshacer
    if (textBox1.CanUndo)
    {
        // deshacer
        textBox1.Undo();
    }
}

 


ir arriba

la Luna del Guille o... el Guille que está en la Luna... tanto monta...