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]
|