Solución: Paciencia y la explicación a continuación.
Una columna combo se trabaja de forma diferente a una columna texto, primero se tiene que llenar los items que tendrá el combo antes de pasar toda la información al grid.
Existen varias maneras de llenar el campo combo. De forma manual ingresando los items en modo de edición, o con un proceso sencillo en modo de ejecución.
Desgraciadamente, para mi ejemplo, no puedo usar ninguna de las maneras anteriores, puesto que necesito llenar el combo, con los datos de una tabla. Así que tuve que crear mi propio proceso.
Private Sub cargar_DataCombo(ByVal dv As DataGridView) Dim adapter As New SqlDataAdapter Using connection As SqlConnection = New SqlConnection(args) 'La variable args contiene la cadena de conexión, llenada anteriormente. adapter = New SqlDataAdapter(select campo_codigo, campo_descripcion from tabla, connection) 'Lleno el DataTable Dim dt As New DataTable() adapter.Fill(dt) 'Indico la columna combo Dim column As DataGridViewComboBoxColumn = _ DirectCast(dv.Columns(0), DataGridViewComboBoxColumn) 'Configuro la columna. With column 'Origen de datos .DataSource = dt 'Nombre del campo cuyos datos se mostraran en la columna .DisplayMember = "campo_descripcion" 'Nombre del campo cuyo valor se devolverá cuando se seleccione un elemento. .ValueMember = "campo_codigo" End With End Using End Sub
El proceso cargar_DataCombo debe ser llamado desde el load de la aplicación, o antes de llenar el grid con la información. Esto quedaría más o menos así:
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load cargar_DataCombo(DataGridView1) 'Aquí sigue el proceso de llenar los datos al grid End Sub
Nota: La función DirectCast sirve para cambiar el tipo de dato a otro compatible, parecida a la función CInt que convierte los datos en enteros, la diferencia es que al DirectCast se le debe indicar el tipo al cual se lo debe convertir.
Una vez que tengo mi SP con el select resultante, lo he ejecutado en visual basic .net y lo he llenado en un DataTable, estoy lista para ponerlo en el grid.
DataGridView1.AutoGenerateColumns = False 'Aquí digo que las columnas no se generen automáticamente, sino que yo las lleno manualmente With DataGridView1 .Columns(0).DataPropertyName = "NombreCampo1" 'Este es el titulo de la columna del select en el SP .Columns(1).DataPropertyName = "NombreCampo2" End With Me.DataGridView1.DataSource = dtTabla 'Aquí conecto los datos del DataTable con el grid
¡HORROR! Me da error al cargar el campo combo.
Esto generalmente sucede porque en el DataPropertyName de una columna combo suelo poner la descripción o el texto del combo, cuando en realidad se debe poner el código del mismo, o mejor dicho, el mismo campo que se configura en el ValueMember del combo.
Me explico mejor.
'Cuando configuro la columna combo al llenarla por primera vez With column 'Nombre del campo cuyos datos se mostraran en la columna .DisplayMember = "campo_descripcion" 'Nombre del campo cuyo valor se devolverá cuando se seleccione un elemento. .ValueMember = "campo_codigo" End With 'Cuando lleno el campo combo del grid con los datos del select resultante del SP With DataGridView1 .Columns(0).DataPropertyName = "campo_codigo" 'Este es el titulo de la columna del select en el SP del combo End With
Note que campo_codigo es el ValueMember de la columna combo, eso es lo que debe llenarse cuando lleno las columnas del grid.