Llenar un ComboBox desde un DataGridView

Iniciado por SilverLycan68, 16 Septiembre 2018, 19:44 PM

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

SilverLycan68

Tengo una funcion que al darle click a una fila del DataGridView llena todos los ComboBox de un formulario.
Código (vbnet) [Seleccionar]

Sub DGVPopulateCMB(ByVal dgvR As DataGridViewRow, ByVal ctrC As Control.ControlCollection)

Dim str As String = Nothing

For Each celda As DataGridViewCell In dgvR.Cells

''PASA POR CADA COMBOBOX
For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
cmb.Items.Clear()

If celda.OwningColumn.Name = cmb.Name.Substring(4) Then
If Not IsDBNull(celda.Value) Then
cmb.Items.Insert(0, celda.Value)

Else
cmb.Items.Insert(0, "NULL")

End If
cmb.Selectedndex = 0
Continue For

End If
Next
Next

End Sub


El problema es cuando reviso el ComboBox esta vacío. No se por que motivo no guarda los valores que tiene el DataGridView.
Me podrian decir la razón de esto.

Serapis

El fallo está en que cada vez que entras al bucle interno, borras el combobox...

Es razonable borrar lo que los combobox tuvieran previasmente, pero.... previamente a la llamada a la función (supongo que esa e sla idea). Luego procede hacer un bucle previo al llenado, justamente para vacíar y nada más...

Ahora bien, es arriesgado por mi parte ponerte un bucle sin más... ya que ignoro (no tengo contexto ninguno de tu aplicación), si se deben borrar todos los combobox o solo algunos específicos... así que te proveo la solución si es ese el caso...

Es decir... que supone que se borran todos los combobox antes de añadir nada más cuando se invoca la función.
Código (vbnet) [Seleccionar]

        Sub DGVPopulateCMB(ByVal dgvR As DataGridViewRow, ByVal ctrC As Control.ControlCollection)
Dim str As String = Nothing

                For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
                        cmb.Items.Clear()
                next

For Each celda As DataGridViewCell In dgvR.Cells

''PASA POR CADA COMBOBOX
For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
' cmb.Items.Clear()

If celda.OwningColumn.Name = cmb.Name.Substring(4) Then
If Not IsDBNull(celda.Value) Then
cmb.Items.Insert(0, celda.Value)
Else
cmb.Items.Insert(0, "NULL")
End If
'cmb.SelectedIndex = 0
'Continue For

End If
Next
Next
         
                ' Resulta estúpido que tras cada añadido deba hacerse al ítem como el actual seleccionado, cuando inmediatamente después (probablemente), va a añadirse otro...
               ' Es mejor diferirlo, y hacerlo una sola vez para cada combo...
                 For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
                        cmb.SelectedIndex = 0
                next
End Sub


El otro caso, es cuando solo aquellos combox afectados (los que vayan a recibir nuevos datos), sean los que deben ser borrados... En ese caso, se debe proveer un banderín por cada combobox, con cada intento de añadir, se verifica si el banderín de borrado ha sido realizado si es false se borra el combobox y acto seguido se marca a true, la siguientes veces (como ya es TRUE) ya solo se añade y no se borra más (hasta la nueva llamada a dicha función claro).


Por último... no es muy aconsejable andar recorriendo todos los controles de un formuario para buscar los de un tipo específico... especialmente si hay muchos controles y la amyoría ni siquiera son de dicho tipo.
Es preferible al caso, crear una colección... y durante el arranque del formulario, recorrer una sola vez toda la colecciónd e controles del formulario y meterlos ahí... luego en los bucles de las funciones donde se precise, se usa esa colección... (que contiene  solo los controles que interesan)... No te pondo código al caso, queda a tu esfuerzo...
Además en este caso resulta también bastante más cómodo tener un array con la cantidad de banderines exactos para todos los combobox que tengamos (pués ya sabemos cuantos hay)...