Validar varios textbox con un grado de complejidad adicional

Iniciado por fr3n3tic, 15 Septiembre 2014, 06:42 AM

0 Miembros y 1 Visitante están viendo este tema.

fr3n3tic

Muy buenas a todos.
Antes de plantear mi consulta, les cuento que estoy haciendo una aplicación windows form en VB.NET 2012 conectada a una base de datos sql server, ahora me encuentro en la etapa de validaciones y si bien puedo hacerla control por control, son muchossss como para hacerlo uno por uno.

A continuación explico todo con imágenes para que quede claro:
Imagen 1:

https://www.dropbox.com/s/m7yutkk5znrpx13/1.JPG?dl=0

En la imagen 1 se aprecia un tab panel llamado "Respuestas correctas" que agrega preguntas de manera dinámica según lo que se indique en el combobox "N° Preguntas" y valida el número de alternativas en el combobox "N° Alternativas", esto está funcionando bien, cuando elijo el número de preguntas se agregan las filas con las preguntas de la forma nombrecontrol.visible = false o true según quiera esconderala o mostrarla y el número de alternativas pueden ser 3, 4 o 5 y las valido con keypress asignando el ascci a las letras que puede agregar el usuario (si son 3, ABC, si son 4 ABCD, si son 5 ABCDE).

El problema de validación que tengo ahora viene en la imagen 2, y tiene que ver con lo siguiente:

Puedo agregar hasta 90 preguntas, y lo que busco es deshabilitar todos los textbox y dejarlos gris exceptuando el que corresponde a la alternativa que eligió el usuario, me explico, si el usuario elige la alterntiva C en la pregunta 50, debiera en la fila 50 solo activarse el textbox abajo del número 3, si elige el D, se activa el textbox del número 4 y así según corresponda la alternativa elegida por el user y que en la que queda activa aparezca el número 1 por defecto (cómo valor numérico, no alfanumérico). El tema es que tendría que hacer esto por cada pregunta puediendo partir en 10 y hasta 90 en bloques de 5 en 5 lo que encuentro es mucho para validar uno a uno. Tengo un panel que agrupa las 10 primera preguntas y luego varios paneles que agrupan preguntas de 5 en 5 hasta llegar a 90, esto me permite mostrar o esconder según la elección de preguntas que haga el usuario.

Otro tema, es que cuando presiono el botón que está entre el checkbox y el último textbox de cada pregunta, me debiese habilitar todos los textbox de esa fila y si presiono el checkbox debiese bloquear todos los textobx de esa fila y dejarlos en cero o limpios cada caja de esa fila.

Aquí va la segunda imagen de referencia.
https://www.dropbox.com/s/pvll2wybxcx3x89/2.jpg?dl=0

TY

Eleкtro

#1
Buenas

1) Las imágenes no se veian, te he editado el post para que al menos se vean las urls, pero creo que no te costaba nada revisar el post que escribiste por ti mismo.

2) Me da la sensación de que estás utilizando el framework de DotNetBar ya que el Form es idéntico al de las plantillas que proporcionan, bueno, obviamente estás utilizando un set de controles profesionales ya sea DotNetBar, Telerik, DevExpress, o etc., y lo que quiero decir con esto es que dichas herramientas profesionales suelen traer mucho más que los propios controles, como métodos de validacion para ciertas tareas, incluso podría haber algún custom ErrorProvider, etc, no te vendría mal preguntar al soporte de la compañia en cuestión para verificar si proporcionan algo en el paquete que te pueda ser útil para resolver el problema que tienes, el cual no se si he llegado a comprender muy bien.

Cita de: fr3n3tic en 15 Septiembre 2014, 06:42 AM
Puedo agregar hasta 90 preguntas, y lo que busco es deshabilitar todos los textbox y dejarlos gris exceptuando el que corresponde a la alternativa que eligió el usuario, me explico, si el usuario elige la alterntiva C en la pregunta 50, debiera en la fila 50 solo activarse el textbox abajo del número 3, si elige el D, se activa el textbox del número 4 y así según corresponda la alternativa elegida por el user y que en la que queda activa aparezca el número 1 por defecto (cómo valor numérico, no alfanumérico). El tema es que tendría que hacer esto por cada pregunta puediendo partir en 10 y hasta 90 en bloques de 5 en 5 lo que encuentro es mucho para validar uno a uno. Tengo un panel que agrupa las 10 primera preguntas y luego varios paneles que agrupan preguntas de 5 en 5 hasta llegar a 90, esto me permite mostrar o esconder según la elección de preguntas que haga el usuario.

Otro tema, es que cuando presiono el botón que está entre el checkbox y el último textbox de cada pregunta, me debiese habilitar todos los textbox de esa fila y si presiono el checkbox debiese bloquear todos los textobx de esa fila y dejarlos en cero o limpios cada caja de esa fila.

Sinceramente, ¿en serio esperas poder recibir ayuda cualificada sin mostrar parte de tú código?, para empezar no sabemos de que manera estás generando los controles dinamicamente por ejemplo el nombre dinámico que les estás asignando (si alguno), pero al instanciar los textboxes, los checkboxes, y los botones, deberías añadirle un Tag a cada control haciendo referencia a la fila en cuestión donde los estás agregando, y así no tendrías dificultades para desactivar los textboxes de una fila en concreto.

No se si esto es lo que buscas, pero creo que podrás adaptarlo a tus necesidades.

Ejemplo:
[youtube=640,360]https://www.youtube.com/watch?v=MJbBf_d27YY[/youtube]

Source:
Código (vbnet) [Seleccionar]
Public Class Form1

   ''' <summary>
   ''' Initializes a new instance of the <see cref="Form1"/> class.
   ''' </summary>
   Public Sub New()

       ' This call is required by the designer.
       InitializeComponent()

       ' Add any initialization after the InitializeComponent() call.
       Me.FormBorderStyle = Windows.Forms.FormBorderStyle.FixedSingle
       Me.StartPosition = FormStartPosition.CenterScreen
       Me.MaximizeBox = False

   End Sub

   ''' <summary>
   ''' Handles the Load event of the Form1.
   ''' </summary>
   Private Shadows Sub Load() Handles MyBase.Load

       Me.CreateRowsOfControls(RowsCount:=5I)

   End Sub

   ''' <summary>
   ''' Creates the controls.
   ''' </summary>
   ''' <param name="RowsCount">The amount of rows of controls to generate.</param>
   Private Sub CreateRowsOfControls(ByVal RowsCount As Integer)

       Me.SuspendLayout()

       For row As Integer = 1I To RowsCount

           For num As Integer = 1I To 5I

               Dim tb As New TextBox With
                   {
                       .Name = String.Format("tb_{0}.{1}", CStr(row), CStr(num)),
                       .Size = New Size(15I, 20I),
                       .Location = New Point((15I * num) + (2I * num), (20I * row) + (5I * row)),
                       .Tag = row
                   }

               Me.Controls.Add(tb)

           Next num

           Dim bt As New Button With
               {
                   .Name = String.Format("bt_{0}", CStr(row)),
                   .Size = New Point(120I, 20I),
                   .Text = String.Format("Desactivar fila nº{0}", CStr(row)),
                   .Location = New Point(Me.Controls(String.Format("tb_{0}.{1}", CStr(row), CStr(RowsCount))).Right + 5I, (20I * row) + (5I * row)),
                   .Cursor = Cursors.Hand,
                   .Tag = New Object() {row, True}
               }

           AddHandler bt.Click, AddressOf bt_Click

           Me.Controls.Add(bt)

       Next row

       Me.ResumeLayout()

   End Sub

   ''' <summary>
   ''' Handles the Click event of the bt controls.
   ''' </summary>
   ''' <param name="sender">The source of the event.</param>
   ''' <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
   Private Sub bt_Click(ByVal sender As Object, ByVal e As EventArgs)

       Dim bt As Button = DirectCast(sender, Button)
       Dim Row As Integer = DirectCast(bt.Tag(0I), Integer)
       Dim Disable As Boolean = DirectCast(bt.Tag(1I), Boolean)

       Dim tbNamePattern As String = String.Format("tb_{0}.", CStr(Row))

       Me.SuspendLayout()

       Select Case Disable

           Case True ' Desactivar controles

               bt.Text = String.Format("Activar fila nº{0}", CStr(Row))
               bt.Tag = New Object() {Row, Not Disable}

               ControlIterator.Disable(Of TextBox)(Me.Controls, tbNamePattern)

               ControlIterator.PerformAction(Of TextBox)(Me.Controls,
                                                         Sub(tb As TextBox)
                                                             tb.BackColor = Color.Black
                                                         End Sub,
                                                         ContainsName:=tbNamePattern)

           Case Else ' Activar controles

               bt.Text = String.Format("Desactivar fila nº{0}", CStr(Row))
               bt.Tag = New Object() {Row, Not Disable}

               ControlIterator.Enable(Of TextBox)(Me.Controls, tbNamePattern)

               ControlIterator.PerformAction(Of TextBox)(Me.Controls,
                                                         Sub(tb As TextBox)
                                                             tb.BackColor = SystemColors.Window
                                                         End Sub,
                                                         ContainsName:=tbNamePattern)

       End Select ' Disable

       Me.ResumeLayout()

   End Sub

End Class


Como te habrás dado cuenta uso una class llamada 'Control Iterator', es una Class que escribí hace tiempo que te puede servir para el propósito del primer problema y del segundo problema, el código es demasiado largo así que aqui te lo dejo en un enlace externo:

Control Iterator for VB.Net (15-Sep-2014)

Saludos.