domingo, 4 de abril de 2010

C# - [Winforms] Como usar el SelectedValue

 

Introducción

En varias oportunidades he notado que trae problemas el incorrecto uso de ciertas propiedades en controles como ser el ComboBox, ListBox, CheckBoxList especialmente cuando estos están bindeados a datos que usan datatables.

Es por eso que aquí se trataran ejemplo de distintas formas de trabajar estos controles unidos a datos, y que propiedades usar cuando se quiere trabajar con ellos.

Uno de los principales problemas es el uso de la propiedad SelectedValue, esta permite tomar el valor del ítem seleccionado por el usuario, pero como manipular esta propiedad depende de la forma en como se haya vinculado el control al origen de datos.

Las distintas formas de trabajar la propiedad estará dada por la asignación o no de un valor en la propiedad ValueMember

Sin asignación del ValueMember

En el Form1 se hace uso de un DataSet Tipado de nombre “ProductosDataSet”, el cual será responsable por medio del TableAdapter (creado por el asistente), de cargar los datos proveniente de la db.

Solo se ha especificado la propiedad DisplayMember, al momento de bindear el DataTable de producto, devuelto por el método creado para tal fin.

[C#]

private void Form1_Load(object sender, EventArgs e)
{
    CargarComboBox();

    CargarListBox();

    CargarCheckBoxList();
}

private void CargarComboBox()
{
    cbProductos.DataSource = ObtenerProductos();
    cbProductos.DisplayMember = "Descripcion";
}

private void CargarListBox()
{
    lbProductos.DataSource = ObtenerProductos();
    lbProductos.DisplayMember = "Descripcion";
}

private void CargarCheckBoxList()
{
    ckbProductos.DataSource = ObtenerProductos();
    ckbProductos.DisplayMember = "Descripcion";
}

[VB.NET]

Private Sub Form1_Load(sender As Object, e As EventArgs)
	CargarComboBox()

	CargarListBox()

	CargarCheckBoxList()
End Sub

   Private Sub CargarComboBox()

       cbProductos.DataSource = ObtenerProductos()
       cbProductos.DisplayMember = "Descripcion"

   End Sub

   Private Sub CargarListBox()

       lbProductos.DataSource = ObtenerProductos()
       lbProductos.DisplayMember = "Descripcion"

   End Sub

   Private Sub CargarCheckBoxList()

       ckbProductos.DataSource = ObtenerProductos()
       ckbProductos.DisplayMember = "Descripcion"

   End Sub

En este caso al inspeccionar la propiedad SelectedValue, todos los controles devolverá un objeto del tipo DataRowView.

[C#]

private void cbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    DataRowView rowView = cbProductos.SelectedValue as DataRowView;
    
   
    lblSeleccionComboBox.Text = string.Format("Id: {0} \nDescripcion: {1} \nPrecio: {2}", 
                                        rowView["IdProducto"], 
                                        rowView["Descripcion"], 
                                        rowView["PrecioUnitario"]);
}

private void lbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    DataRowView rowView = lbProductos.SelectedValue as DataRowView;

    lblSeleccionListBox.Text = string.Format("Id: {0} \nDescripcion: {1} \nPrecio: {2}", 
                                        rowView["IdProducto"], 
                                        rowView["Descripcion"], 
                                        rowView["PrecioUnitario"]);

}

private void ckbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    DataRowView rowView = ckbProductos.SelectedValue as DataRowView;

    txtSeleccionCheckBoxList.Text = string.Format("Id: {0} \r\nDescripcion: {1} \r\nPrecio: {2}", 
                                        rowView["IdProducto"], 
                                        rowView["Descripcion"], 
                                        rowView["PrecioUnitario"]);
}

private void btnCheckedItems_Click(object sender, EventArgs e)
{
    txtSeleccionCheckBoxList.Text = "";

    foreach (DataRowView rowView in ckbProductos.CheckedItems)
    {
        txtSeleccionCheckBoxList.Text += string.Format("Id: {0} \r\nDescripcion: {1} \r\nPrecio: {2}\r\n\r\n", 
                                                            rowView["IdProducto"], 
                                                            rowView["Descripcion"], 
                                                            rowView["PrecioUnitario"]);
    }

}

[VB.NET]

Private Sub cbProductos_SelectedIndexChanged(sender As Object, e As EventArgs)
	Dim rowView As DataRowView = TryCast(cbProductos.SelectedValue, DataRowView)


       lblSeleccionComboBox.Text = String.Format("Id: {1} {0}Descripcion: {2} {0}Precio: {3}", _
                                                 Environment.NewLine, _
                                                 rowView("IdProducto"), _
                                                 rowView("Descripcion"), _
                                                 rowView("PrecioUnitario"))
End Sub

   Private Sub lbProductos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

       Dim rowView As DataRowView = TryCast(lbProductos.SelectedValue, DataRowView)

       lblSeleccionListBox.Text = String.Format("Id: {1} {0}Descripcion: {2} {0}Precio: {3}", _
                                                 Environment.NewLine, _
                                                 rowView("IdProducto"), _
                                                 rowView("Descripcion"), _
                                                 rowView("PrecioUnitario"))
   End Sub

   Private Sub ckbProductos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

       Dim rowView As DataRowView = TryCast(ckbProductos.SelectedValue, DataRowView)

       txtSeleccionCheckBoxList.Text = String.Format("Id: {1} {0}Descripcion: {2} {0}Precio: {3}", _
                                         Environment.NewLine, _
                                         rowView("IdProducto"), _
                                         rowView("Descripcion"), _
                                         rowView("PrecioUnitario"))
   End Sub

   Private Sub btnCheckedItems_Click(ByVal sender As Object, ByVal e As EventArgs)

       txtSeleccionCheckBoxList.Text = ""

       For Each rowView As DataRowView In ckbProductos.CheckedItems

           txtSeleccionCheckBoxList.Text += String.Format("Id: {1} {0}Descripcion: {2} {0}Precio: {3}{0}{0}", _
                                             Environment.NewLine, _
                                             rowView("IdProducto"), _
                                             rowView("Descripcion"), _
                                             rowView("PrecioUnitario"))
       Next

   End Sub

Seguramente uno se preguntara porque este dato en concreto, bien resulta que este representa una vista de la fila del DataTable, y como solo estamos seleccionado un ítem individual en el control, este devolverá solo una fila (row) del DataTable usado para vincular el dato de ese ítem en particular.

 

Asignando un valor al ValueMember

En el Form2, se define el valor de uno de los campos del origen de datos en la propiedad ValueMember, esto hace que la aplicación trabaje de una forma distinta.

[C#]

private void Form2_Load(object sender, EventArgs e)
{
    CargarComboBox();

    CargarListBox();

    CargarCheckBoxList();
}

private void CargarComboBox()
{
    cbProductos.DisplayMember = "Descripcion";
    cbProductos.ValueMember = "IdProducto";
    cbProductos.DataSource = ObtenerProductos();

}

private void CargarListBox()
{
    lbProductos.DisplayMember = "Descripcion";
    lbProductos.ValueMember = "IdProducto";
    lbProductos.DataSource = ObtenerProductos();

}

private void CargarCheckBoxList()
{
    ckbProductos.ValueMember = "IdProducto";
    ckbProductos.DataSource = ObtenerProductos();
    ckbProductos.DisplayMember = "Descripcion";
}

[VB.NET]

Private Sub Form2_Load(ByVal sender As Object, ByVal e As EventArgs)
    CargarComboBox()

    CargarListBox()

    CargarCheckBoxList()
End Sub

Private Sub CargarComboBox()

    cbProductos.DisplayMember = "Descripcion"
    cbProductos.ValueMember = "IdProducto"
    cbProductos.DataSource = ObtenerProductos()

End Sub

Private Sub CargarListBox()

    lbProductos.DisplayMember = "Descripcion"
    lbProductos.ValueMember = "IdProducto"
    lbProductos.DataSource = ObtenerProductos()

End Sub

Private Sub CargarCheckBoxList()

    ckbProductos.ValueMember = "IdProducto"
    ckbProductos.DataSource = ObtenerProductos()
    ckbProductos.DisplayMember = "Descripcion"

End Sub

Es importante destacar en este punto que la asignación de las propiedades debe realizarse antes de bindear la información, ya que si la propiedad ValueMember es asignada después esta no tendrá efecto.

[C#]

private void cbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    int IdProducto = Convert.ToInt32(cbProductos.SelectedValue);
    string Descripcion = Convert.ToString(cbProductos.Text);
    
   
    lblSeleccionComboBox.Text = string.Format("Id: {0} \nDescripcion: {1}",
                                        IdProducto, 
                                        Descripcion);
}

private void lbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    int IdProducto = Convert.ToInt32(lbProductos.SelectedValue);
    string Descripcion = Convert.ToString(lbProductos.Text);


    lblSeleccionListBox.Text = string.Format("Id: {0} \nDescripcion: {1}",
                                        IdProducto,
                                        Descripcion);

}

private void ckbProductos_SelectedIndexChanged(object sender, EventArgs e)
{
    int IdProducto = Convert.ToInt32(ckbProductos.SelectedValue);
    string Descripcion = Convert.ToString(ckbProductos.Text);


    txtSeleccionCheckBoxList.Text = string.Format("Id: {0} \r\nDescripcion: {1}",
                                        IdProducto,
                                        Descripcion);
}

private void btnCheckedItems_Click(object sender, EventArgs e)
{
    txtSeleccionCheckBoxList.Text = "";

    foreach (DataRowView rowView in ckbProductos.CheckedItems)
    {
        txtSeleccionCheckBoxList.Text += string.Format("Id: {0} \r\nDescripcion: {1} \r\nPrecio: {2}\r\n\r\n", 
                                                            rowView["IdProducto"], 
                                                            rowView["Descripcion"], 
                                                            rowView["PrecioUnitario"]);
    }

}

 

[VB.NET]

Private Sub cbProductos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim IdProducto As Integer = Convert.ToInt32(cbProductos.SelectedValue)
    Dim Descripcion As String = Convert.ToString(cbProductos.Text)


    lblSeleccionComboBox.Text = String.Format("Id: {1} {0}Descripcion: {2}", _
                                              Environment.NewLine, _
                                              IdProducto, _
                                              Descripcion)
End Sub

Private Sub lbProductos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim IdProducto As Integer = Convert.ToInt32(lbProductos.SelectedValue)
    Dim Descripcion As String = Convert.ToString(lbProductos.Text)


    lblSeleccionListBox.Text = String.Format("Id: {1} {0}Descripcion: {2}", _
                                              Environment.NewLine, _
                                              IdProducto, _
                                              Descripcion)
End Sub

Private Sub ckbProductos_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim IdProducto As Integer = Convert.ToInt32(ckbProductos.SelectedValue)
    Dim Descripcion As String = Convert.ToString(ckbProductos.Text)


    txtSeleccionCheckBoxList.Text = String.Format("Id: {1} {0}Descripcion: {2}", _
                                      Environment.NewLine, _
                                      IdProducto, _
                                      Descripcion)
End Sub

Private Sub btnCheckedItems_Click(ByVal sender As Object, ByVal e As EventArgs)

    txtSeleccionCheckBoxList.Text = ""

    For Each rowView As DataRowView In ckbProductos.CheckedItems

        txtSeleccionCheckBoxList.Text += String.Format("Id: {1} {0}Descripcion: {2} {0}Precio: {3}{0}{0}", _
                                          Environment.NewLine, _
                                          rowView("IdProducto"), _
                                          rowView("Descripcion"), _
                                          rowView("PrecioUnitario"))
    Next

End Sub

Ahora si, al momento de recuperar el valor este retornara en la propiedad SelectedValue un dato simple, en este caso un entero por tratarse del Id del Producto.

Aquí ya no podrá recuperarse el precio en la misma acción, o al menos no con la propiedad SelectedValue, para poder tomar el DataRowView, se deberá recurrir al SelectedItem

 

Aclaración

Para cambiar la ejecución de un Formulario a otro, deberás modificar el archivo Program.cs o Program.vb según el lenguaje usado

cambiando la línea: Application.Run(new Form1());

por el nombre de la clase del formulario que quiere ejecutarse

 

[C#]
[VB.NET]

21 comentarios:

  1. Muy currado el tema, es e agrader que haya personas como usted por aquí.

    Una duda, veo que en los códigos fuente incluye un dibujo de una flecha verde curvada. ¿Lo sacas directamente de Visual Studio o lo pusiste usted mismo de alguna manera?

    Saludo.

    ResponderEliminar
  2. hola

    Imagino que te refierea a la flecha que usa la seccion de codigo definida en el articulo.

    En realidad esta la pone de forma automatica el plugin para publicar codigo que estoy usando.

    Los bloque de codigo estan publicados usando un plugin (que uso integrado al Windows Live Writer) de Syntax Highlighting, que aplcia estilos, colores, y no se si has visto una pequeña barra que parece cuando pasas el cursos sobre ese seccion.

    Bien en esa pequeña toolbar del bloque de codigo veras una opcion para desplegar el codigo sin formato, esto es util si es que quieres copiarlo, y usarlo en tu desarrollo

    saludos

    ResponderEliminar
  3. Saludos Leandro, la verdad tu codigo me ha sido de gran ayuda, primero te felicito por este gran aporte, pero ahora tengo una inquietud y es al momento de usar este esquema para llenar en mi caso actual un checklistbox, funciona a la perfeccion llenando con los registro de mi base de datos, pero me gustaria saber si existe la posibilidad de hacer un check automatico dependiendo de un atributo de mi tabla, ejemplo un campo llamado 'status' y me aparesca en check el item del checklistbox si el valor del campo 'status' = 1 o uncheck si 'status' = 0, es posible esto?
    Anexo. trabajo con vb.net 2008

    ResponderEliminar
  4. hola Alexis,
    que bueno que resulto util el articulo

    Sobre tu consulta puedo comentarte que el CheckBoxList no tinene una propiedad especifica para asignar que items debe estar marcado segun un objeto de dato concreto.

    Pero si podrias implementar tu mismo la seleccion

    Igualmente tengo una duda porque en tu consulta solo mencionas un campo "status", pero el checkbox lists representa un numero de checks, para lo cual primero deberas identificar cual es el que representa al "status", para recien alli marcarlo, o es que estas usando un checkbox comun ?

    Como comente si usas el checkboxlist, primero hay que idnetificar que check es el del status, para ello deberas recorrer item a item en un for each y preguntar si es el check que quieres marcar

    foreach(object item in checkedListBox1.Items) {

    if(Convert.ToString(item) == "status")
    {
    if(estado)
    checkedListBox1.SetItemChecked(checkedListBox1.Items.IndexOf(item), true);

    break;
    }

    }

    CheckedListBox.Items

    La forma en como compares el item puede variar, ya que al recorrer el checkboxlist pasara lo mismo que menciona este articulo, si no asignas el ValueMember, este podrias retornar un DataRow, por lo que deberas usar

    if(Convert.ToString(item["campo"]) == "status")

    A donde apunto es que en el for each cada item es del tipo object, y esto puede ser un string u otro tipo de objeto segun como hayas realziado el binding del control.

    Ademas veras que use esto: if(estado)

    Aqui estado es el valor que obtienes de una consulta previa la que comentas si es 0 o 1, por supuesto convertido a bool asi es mas directo

    Bueno espero esto de al menos una pista de como trabajar con el control, como veras no es tan directo.

    saludos

    ResponderEliminar
  5. Leandro muy interesante el tema.
    Te tenía una consulta a mi recién me ocurrió el problema de la configuración de los combobox y el origen de datos, siempre lo había hecho primero poniendo el origen de datos algo así
    Me.cbpPais.DataSource = paises.Listado
    Me.cbpPais.DisplayMember = "NombrePais"
    Me.cbpPais.ValueMember = "IdPais"
    y no había problema
    el error
    La conversión del tipo 'DataRowView' en el tipo 'Integer' no es válida
    recién me salió cuando traté de hacer lo mismo pero con datos que en mi base de datos tenian el tipo integer.
    Se solucionó poniendo el origen al final como leí acá
    A que se debe esto?
    solo ocurre con datos del tipo integer??

    ResponderEliminar
  6. hola Augusto

    En realidad este tema lo atribuyo a una particularidad de los controles Winforms al vincularse a los datos.

    Como habras visto en las pruebas del articulos, uno puede necesitar el DataView que se bindeo al item, mas que nada cuando hay objetos mas complejos.

    Ojo esto no solo pasa con el datatable, si suas listas del tipo genericas List devolvera una instancia de cliente cuando tomes el valor.

    No es un tema del tipo de datos, que sea un entero o una clase sucede igual.

    Es mas imagino no has visto nada de WPF, en este se ve que se apiolaron de este defecto y ahora los controles cuentan con propiedades especificas para obtener o la entidad o el valor, cosa que aqui no se puede.
    En WPF uno usa una propiedad y obtiene la instancia del item de ese item, o sua otra propiedad y obtiene el valor simple de ese item del control.
    Eso esta muy piola, pero bueno es en WPF.

    saludos

    ResponderEliminar
  7. Hola Leandro, disculpa que realice mi comentario en una entrada antigua.

    Tengo una consulta similar a la de Alexis -Pax- Sanchez

    Tengo un CheckedListBox que he llenado previemente con un datatable, ahora, tengo que checar ciertos items, pero el detalle es que estos estan en la base de datos, entonces lleno otro datatable solamente con la descripción de los items a checar. Trato de hacerlo de esta manera, pero me da error:
    For Each dr As DataRow In dtSeleccionados.Rows
    clbTipoAccidente.SetItemChecked(clbTipoAccidente.Items.IndexOf(Convert.ToString(dr(0)).Trim), True)
    Next

    El IndexOf que me envía es -1 y no debería de ser así por que los datos que vienen en ese datatable son exactamente los mismos que los del datatable con el que se llenó el CheckedListBox.

    Espero su comentario.

    ResponderEliminar
  8. hola JT

    el tema es que el IndexOf() no realiza una busqueda por el valor de los check

    porque no usas linq para buscar el item y despues marcarlo

    http://stackoverflow.com/questions/471595/casting-an-item-collection-from-a-listbox-to-a-generic-list

    en tu caso no uses Checkeditems sino que usarias Items directamente aplicando un Where de linq para filtrar por el valor que recuperas del datatable

    cuando obtienes el item ahi recien lo marcarias, pero debes buscar primero por valor

    saludos

    ResponderEliminar
  9. Buenas Tardes
    Perdón por realizar mi pregunta en este tema, tengo un problema, más bien una duda, quiero copiar los elementos de una lista que se encuentran en mi BindingSource, primero lleno un DataView con el DataSource de mi BindingSource de esta manera:

    this._viewFolioNombres = (DataView)this.folio_nombresBindingSource.List;

    _viewFolioNombres es mi DataView donde guardo los elementos de la lista que quiero insertar en otro BindingSource, el problema es que lanza la siguiente excepción:
    "Cannot insert external objects to this list"

    La línea que lo lanza es la siguiente:
    this.oficio_foliosBindingSourceClon.Add(this._viewFolioOficios)

    El Binding de origen tiene la propiedad DataMember de la siguiente manera: "FK_oficios_oficio_folios" y el Binding de destino debería de tener la siguiente "FK_oficiosBAN_oficio_foliosBAN".

    Cuando establezco la propiedad de Data Source del binding destino de la siguiente manera:

    this.oficio_foliosBindingSourceClon.DataSource = this._viewFolioOficios

    No hay problema, sólo que no establecida el Data Member.

    Mira, lo que busco es lo siguiente, el usuario llena un DataGridView que tiene enlazado el BindingSource siguiente: folio_nombresBindingSource

    Lo que quiero es llevarme esos datos a otro grid que está enlazado
    con un BindingSource llamado oficio_foliosBindingSourceClon
    Ambos tienen diferente DataMember, no sé me ocurre alguna manera de copiar o traspasar los datos de ese grid en el cual el usuario tecleo datos al otro.

    Espero haber explicado algo mi problemática, espero que te des un tiempo para leer esto.

    Muchas gracias por tu blog, me ha sido de gran ayuda.

    Saludos desde México

    ResponderEliminar
  10. Hola que tal, buen día, con respecto a los checkbox tengo una duda que ya eh buscado mucho por internet y no encuentro solucion. Manejo una lista donde se seleccionan los checkboxList y los datos contenidos en ellos se almacenan en una base de datos, ahora bien como se puede hacer para mostrar nuevamente el checkboxlist y que tenga marcada las casillas que se seleccionaron al principio, gracias de antemano.

    ResponderEliminar
  11. hola thanny

    es un desarrollo web o desktop el que estas desarrollando?
    usas el control CheckedListBox ?

    porque podrias ayudarte con linq para cruzar los datos que recuperas de la query y los items del control para conocer cuales debes marcar

    saludos

    ResponderEliminar
  12. Porque me sale error al momento de iniciar mi formulario en esta parte de codigo, aun poniendo una condicional para que no vaya al error.

    Dim ex As String


    ex = cbmes.Text.Trim

    If (ex = "" And ex Is Nothing Or ex = "System.Data.DataRowView") Then
    Else
    CargaGrilla(cbanio.SelectedValue, cbmes.SelectedValue, 2)
    End If


    Private Sub CargaGrilla(ByVal an As Int16, ByVal mes As Int16, ByVal mon As Int16)



    dgmonedav.DataSource = blMonedaValor.ListarLike(an, mes, mon)




    gbcliente.Enabled = False
    End Sub


    Private Sub frmmonedavalorValor_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    CargaCombos()

    CargaGrilla(Year(Date.Now), Month(Date.Now), 2)

    End Sub

    ResponderEliminar
  13. hola Luis

    se deberia usar usa el AndAlso o el OrElse para que no evalue la otra parte de la condicion

    recuerda ademas poner la validacion del null primero

    saludos

    ResponderEliminar
  14. Hola Alejandro, agraderte primero, y tambien culimnar con mi pregunta, acotando que el datasouurce debe ponder o setarse despues de del displaymemer y valuemember sinoo sale error.

    Espero que también haga un aporte.

    Feliz día del trabajador.

    ResponderEliminar
  15. hola Luis

    no creo que tengas un error si lo defines despues de asignar el datasource

    simplemente quizas cuando quieras acceder a la seleccion del item obtengas la entidad en lugar de un valor simple

    saludos

    ResponderEliminar
  16. tengo un problema intento guardar el valor de un combobox en un txt
    en mi modulo tengo la siguiente funcion donde hago la consulta pero cuando cargo el combo recibo el selectvalue pero me manda "0"

    Sub llnarombobox(ByVal cb As ComboBox)
    Try
    'adapter = New SqlDataAdapter("Select id_docente,(nombre + \' \' + ap) as Name_Full FROM docente", conexion)
    enunciado = New SqlCommand("SELECT (id_docente)as Clave, (ap + ' ' + am+' '+nombre) AS Docente FROM docente ORDER BY ap ASC, am ASC, nombre asc", conexion)
    respuesta = enunciado.ExecuteReader
    While respuesta.Read
    cb.Items.Add(respuesta.Item("Docente"))
    cb.DisplayMember = respuesta("Docente")
    cb.ValueMember = respuesta("Clave")
    'cb.ValueMember.("id_docente")
    End While
    respuesta.Close()
    Catch ex As Exception
    MessageBox.Show("error al cargar " + ex.ToString)
    End Try

    End Sub

    en mi fomulario tengo el siguiente evento del combobox


    Private Sub cmbxDocente_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cmbxDocente.SelectedIndexChanged
    Dim IdProducto As Integer = Convert.ToInt32(cmbxDocente.SelectedValue)
    Dim Descripcion As String = Convert.ToString(cmbxDocente.Text)


    txtMateria.Text = String.Format("Id: {1} {0}Descripcion: {2}", _
    Environment.NewLine, _
    IdProducto, _
    Descripcion)
    End Sub

    agradeceria su ayuda!

    ResponderEliminar
    Respuestas
    1. hola
      Pero no se usa el reader con el DisplayMember y ValueMember, sino que en el while deberias cargar una lista de una entidad que definas y despues asignar el DataSource del combo
      No aplica el Items.Add() si usas el DisplayMember y ValueMember
      Debes definir una clase con al menso dos propiedades y cargar en el while del reader una lista generica definida del tipo de la clase, esa lista la asignas al DataSource
      saludos

      Eliminar
  17. gracias por ayudarme a aprobar 5to añoo

    ResponderEliminar
  18. Hola Leandro, mucho gusto.

    antes que nada, me encanta tu blog, y tus participaciones en los foros de Microsoft.

    bueno, tengo una duda sobre este problema.

    tengo este combobox.
    private void cargarTipoProducto()
    {
    GIVL.TipoProducto tipoProductoLogica = new GIVL.TipoProducto();
    cmbTipoProducto.ItemsSource = tipoProductoLogica.buscarTipoProducto();
    cmbTipoProducto.DisplayMemberPath = "tipo_producto";
    cmbTipoProducto.SelectedValue = "tipoProductoID";
    cmbTipoProducto.SelectedIndex = 0;
    }
    hasta aqui todo esta perfecto, me muestra los datos, pero el problema que tengo es al buscar un tipo de producto en especifico como por ejemplo ya teniendo que cargue desde el tipoProductoId = 4;

    se que deberia ser asi: cmbTipoProducto.SelectedIndex = 4;

    pero cuando los carga no están por id, si no por orden alfabético.

    he tratado con:

    this.unidadComboBox.SelectedValue = tp.tipo_producto;

    espero y me puedas ayudar,

    ResponderEliminar
  19. Estimado Leandro,
    Antes que todo Agradecer tu tiempo y pedagogia para explicar, tengo un problema con el select value y creo que este se susita cuando no ingreso un dato en el combobox y como el selectvalue hay que convertitlo a int no puede hacer la conversion de un valor vacio. Y no se como puedo hacer que pase un valor null si el combobox está vacio

    ResponderEliminar
  20. Muchas gracias amigo!! me fue de utilidad!!

    ResponderEliminar