Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: SilverLycan68 en 16 Septiembre 2018, 19:44 pm



Título: Llenar un ComboBox desde un DataGridView
Publicado por: SilverLycan68 en 16 Septiembre 2018, 19:44 pm
Tengo una funcion que al darle click a una fila del DataGridView llena todos los ComboBox de un formulario.
Código
  1. Sub DGVPopulateCMB(ByVal dgvR As DataGridViewRow, ByVal ctrC As Control.ControlCollection)
  2.  
  3. Dim str As String = Nothing
  4.  
  5. For Each celda As DataGridViewCell In dgvR.Cells
  6.  
  7. ''PASA POR CADA COMBOBOX
  8. For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
  9. cmb.Items.Clear()
  10.  
  11. If celda.OwningColumn.Name = cmb.Name.Substring(4) Then
  12. If Not IsDBNull(celda.Value) Then
  13. cmb.Items.Insert(0, celda.Value)
  14.  
  15. Else
  16. cmb.Items.Insert(0, "NULL")
  17.  
  18. End If
  19. cmb.Selectedndex = 0
  20. Continue For
  21.  
  22. End If
  23. Next
  24. Next
  25.  
  26. End Sub
  27.  

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.


Título: Re: Llenar un ComboBox desde un DataGridView
Publicado por: Serapis en 17 Septiembre 2018, 11:37 am
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
  1.        Sub DGVPopulateCMB(ByVal dgvR As DataGridViewRow, ByVal ctrC As Control.ControlCollection)
  2. Dim str As String = Nothing
  3.  
  4.                For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
  5.                        cmb.Items.Clear()
  6.                next
  7.  
  8. For Each celda As DataGridViewCell In dgvR.Cells
  9.  
  10. ''PASA POR CADA COMBOBOX
  11. For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
  12. ' cmb.Items.Clear()
  13.  
  14. If celda.OwningColumn.Name = cmb.Name.Substring(4) Then
  15. If Not IsDBNull(celda.Value) Then
  16. cmb.Items.Insert(0, celda.Value)
  17. Else
  18. cmb.Items.Insert(0, "NULL")
  19. End If
  20. 'cmb.SelectedIndex = 0
  21. 'Continue For
  22.  
  23. End If
  24. Next
  25. Next
  26.  
  27.                ' 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...
  28.               ' Es mejor diferirlo, y hacerlo una sola vez para cada combo...
  29.                 For Each cmb As ComboBox In ctrC.OfType(Of ComboBox)
  30.                        cmb.SelectedIndex = 0
  31.                next
  32. End Sub
  33.  

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)...