none
Recorrer textbox de un formulario y dar Foco a los textbox que tengan ReadOnly=false

    Pregunta

  • De antemano quiero agradecer por la oportuna ayuda, quisiera saber si me pueden ayudar con lo siguiente: tengo 5 textbox y 5 checkbox por cada textbox todos dentro de un Groupbox. Los textbox empiezan con la propiedad readonly=true y cuando selecciono un checkbox el textbox cambia la propiedad readonly=false. Lo que deseo es que despues de escribir en el textbox y presionar enter el foco pase al siguiente textbox que tenga la propiedad readonly=false, tengo el siguiente codigo pero no logro hacerlo funcionar.

    PD: El presionar el enter esta listo, lo que me falta es dar el foco al siguiente textbox que tenga la propiedad readonly=false.  

    Private Function darfocotextbox() As Integer
            For Each control As Control In GroupControl3.Controls
                ' si algún control es un textbox
                If TypeOf control Is TextBox Then
                    ' entonces revisamos su valor
                    Dim checktextbox As TextBox = TryCast(control, TextBox)
                    'pasamos el foco

                  if checktexbox.readonly=false then

                  checktextbox.Focus()

                  end if

                End If
            Next
        End Function




    lunes, 6 de marzo de 2017 2:19

Respuestas

  • Marzamsteel,

    De acuerdo, borra todo lo que has escrito en el evento KeyPress y reemplazar por el siguiente código:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    	For Each txt As TextBox In Me.GroupBox1.Controls.OfType(Of TextBox)
    		AddHandler txt.KeyPress, AddressOf txt_KeyPress
    	Next
    	
    End Sub


    Private Sub txt_KeyPress(sender As Object, e As KeyPressEventArgs)
    
    	'Asignar a la variable txt la referencia del objeto que produce el evento KeyPress
    	Dim txt = DirectCast(sender, TextBox)
    
    	'funcion que valida que solo se ingrese numeros hasta 3 decimales
    	'Call Numeros_en_texbox(e, 3, txt)
    
    	If e.KeyChar = Convert.ToChar(Keys.Return) Then '¿Se presiono la tecla [ENTER]?
    		e.Handled = True
    
    		If txt.Text = "0" Or txt.Text = "0," Then
    			txt.Clear()
    		Else
    			'Obtener todos los objetos de tipo TexBox con ReadOnly configurado en False
    			Dim Controles = Me.GroupBox1.Controls.OfType(Of TextBox).
                                                  Where(Function(t) Not t.ReadOnly)
    			'Obtener el índice del orden de tabulación actual
    			Dim TabIndex = ActiveControl.TabIndex
    
    			'Obtener el siguiente objeto de tipo TextBox, la búsqueda es cíclica
    			Dim txtNext = Controles.Where(Function(t) t.TabIndex >
    				IIf(Controles.Max(Function(c) c.TabIndex) = TabIndex, -1, TabIndex)).
    				OrderBy(Function(c) c.TabIndex).FirstOrDefault()
    
    			If txtNext IsNot Nothing Then '¿Existe una referencia válida?
    				txtNext.Focus() 'Asignar el foco a la referencia seleccionada
    			End If
    		End If
    	End If
    
    End Sub


    He comentado la llamada a la función 'Numeros_en_textbox' porque no es evidente para mi la tarea que realiza dentro del bloque de código que nos compartes o como es que interactúa con el código del controlador del evento.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Marzamsteel martes, 7 de marzo de 2017 0:43
    martes, 7 de marzo de 2017 0:22

Todas las respuestas

  • Marzamsteel,

    Lo primero que te puedo sugerir es que conectes el evento KeyDown de todos los cuadros de texto contenidos en el objeto de tipo GroupBox a un controlador de eventos (en vez de la función darfocotextbox()):

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    	For Each txt As TextBox In Me.GroupBox1.Controls.OfType(Of TextBox)
    		AddHandler txt.KeyDown, AddressOf txt_KeyDown
    	Next
    
    End Sub

    El objetivo es poder gestionar el foco cada vez que se detecte la pulsación de la tecla [ENTER]:

    Private Sub txt_KeyDown(sender As Object, e As KeyEventArgs)
    
    	If e.KeyCode = Keys.Enter Then
    		Dim txt = Me.GroupBox1.Controls.OfType(Of TextBox).
                    Where(Function(t) Not t.ReadOnly AndAlso t.TabIndex > ActiveControl.TabIndex).
                    OrderBy(Function(c) c.TabIndex).FirstOrDefault()
    
    		If txt IsNot Nothing Then
    			txt.Focus()
    		End If
    	End If
    
    End Sub

    No olvides indicar el espacio de nombres: Imports System.Linq


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    lunes, 6 de marzo de 2017 4:19
  • Amigo muchas gracias por la ayuda, ¡¡funciona le lujo!! pero se me presento otro inconveniente. Para que me funcione el código que me proporcionaste tengo que eliminar el evento keypress del textbox. Por lo que en ese evento tengo la validación de lo que se ingresa en el textbox y la comprobación de cuando se presiona Enter. Como me podrias ayudar para solucionar este inconveniente. 

     Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
        Try
                'funcion que valida que solo se ingrese numeros hasta 3 decimales
                Call Numeros_en_texbox(e, 3, CType(sender, TextBox))
                'codigo en el que se comprueba si se presiono enter
                If e.KeyChar = Convert.ToChar(Keys.Return) Then
                    e.Handled = True ' ... evito el pitido
                    If TextBox1.Text = "0" Or TextBox1.Text = "0," Then
                        TextBox1.Clear()
                        TextBox1.Focus()
                    Else
                        'doy el foco al siguiente control. Aqui se suponia que iba la funcion darfocotextbox()
                    End If
                End If
            Catch ex As Exception

            End Try
        End Sub

    lunes, 6 de marzo de 2017 23:31
  • Marzamsteel,

    De acuerdo, borra todo lo que has escrito en el evento KeyPress y reemplazar por el siguiente código:

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
    	For Each txt As TextBox In Me.GroupBox1.Controls.OfType(Of TextBox)
    		AddHandler txt.KeyPress, AddressOf txt_KeyPress
    	Next
    	
    End Sub


    Private Sub txt_KeyPress(sender As Object, e As KeyPressEventArgs)
    
    	'Asignar a la variable txt la referencia del objeto que produce el evento KeyPress
    	Dim txt = DirectCast(sender, TextBox)
    
    	'funcion que valida que solo se ingrese numeros hasta 3 decimales
    	'Call Numeros_en_texbox(e, 3, txt)
    
    	If e.KeyChar = Convert.ToChar(Keys.Return) Then '¿Se presiono la tecla [ENTER]?
    		e.Handled = True
    
    		If txt.Text = "0" Or txt.Text = "0," Then
    			txt.Clear()
    		Else
    			'Obtener todos los objetos de tipo TexBox con ReadOnly configurado en False
    			Dim Controles = Me.GroupBox1.Controls.OfType(Of TextBox).
                                                  Where(Function(t) Not t.ReadOnly)
    			'Obtener el índice del orden de tabulación actual
    			Dim TabIndex = ActiveControl.TabIndex
    
    			'Obtener el siguiente objeto de tipo TextBox, la búsqueda es cíclica
    			Dim txtNext = Controles.Where(Function(t) t.TabIndex >
    				IIf(Controles.Max(Function(c) c.TabIndex) = TabIndex, -1, TabIndex)).
    				OrderBy(Function(c) c.TabIndex).FirstOrDefault()
    
    			If txtNext IsNot Nothing Then '¿Existe una referencia válida?
    				txtNext.Focus() 'Asignar el foco a la referencia seleccionada
    			End If
    		End If
    	End If
    
    End Sub


    He comentado la llamada a la función 'Numeros_en_textbox' porque no es evidente para mi la tarea que realiza dentro del bloque de código que nos compartes o como es que interactúa con el código del controlador del evento.


    Espero que la información proporcionada te haya sido de utilidad, quedo atento a tus comentarios.
    • Marcado como respuesta Marzamsteel martes, 7 de marzo de 2017 0:43
    martes, 7 de marzo de 2017 0:22
  • Miillll Gracias sensei!!!!!. Justo lo que necesitaba. 
    martes, 7 de marzo de 2017 0:43