Usuario
ComboBox y SelectedValue

Pregunta
-
Hola a todos.
Tengo este código en mi proyecto winform vb.net. En el evento Load de formulario coloque esto para cargar uno de varios combos.
Me.ComboBoAula.DisplayMember = "aula"
Me.ComboBoAula.ValueMember = "codaul"
Dim aul = From a In na.Aulas
Select a
Me.ComboBoAula.DataSource = aulMe.ComboBoAula.Text = "Seleccione una"
Se cargan muy bien los combos con este método, pero el problema esta en que los combos aparecen preselencionados con el primer elemento de su lista.
Si le asigno esta linea Me.ComboBoAula.Text = "Seleccione una" antes del DataSource, no aparece el texto pero si la preseleccion. Si se lo asigno después del DataSource, aparece el texto, pero no cambia el valor del combo al asignarle un valor a su SelectedValue que, asigno desde valores tomados de un DataGrid.
Que puedo hacer, que esta malo?
Todas las respuestas
-
Hola, deberías crearte un elemento dentro del DataSource que contenga el texto "Seleccione una" y asignarle un objeto que vos sepas que no pertenece a la lista de valores.
Por ejemplo, si lo que vas a representar en el combo son Aulas, y cada Aula tiene un Id numérico mayor que cero podrías asignarle enteros a los values y a los display el nombre del aula. Para el elemento "blank" podrías asignarle un id negativo. Cuando valides los datos debes comprobar que el value del combo es mayor que cero, sino mostrar mensaje de "debe seleccionar uno".
Puede que este sea un pensamiento muy Web por mi parte (porque en web solo podemos guardar cosas serializables y livianas en el value), pero es una solución.
Otra que tenés es guardar el elemento Aula entero en el value como estás haciendo y el blank item asignar un null. Esta opción es más fácil pero si por ejemplo en un futuro te interesa agregar otros elementos, como por ejemplo la posibilidad de seleccionar "Todas", o algo por el estilo no podrías seleccionarlo con el null también.
La última y que menos me gusta sería comparar las cadenas, pero es horrible en eficiencia y poco mantenible...
Salu2
-
"Hola, deberías crearte un elemento dentro del DataSource que contenga el texto "Seleccione una" y asignarle un objeto que vos sepas que no pertenece a la lista de valores."
Gracias Matias.
Ya había pensado en esa posibilidad pero, la veo poco practica al momento de realizar mantenimientos de tablas en la BD. Tendría que realizar vaciados de tablas con condición de no borrar el primer registro. Todo esto en cada caso.
Así como también, tener pendiente que solo el usuario administrador pueda borrar o modificar este registro. De modo que tendría que desarrollar permisos y accesos especializados.
Mas bien veo este problema como un error de la herramienta, pues no cumple a cavalidad con lo que reza en su definición. Con el agravante de que funciona bien a capricho, creando con esto gran confucion y frustración en el desarrollador.
Gracias.
-
Hola:
La otra opción y la mas viable es que antes de que enlaces la query al datasource del combo le insertes un valor al principio, en el resultado de tu query podrías pasarlo a una lista por medio de Tolist() y después usar el insert para definir el valor a insertar y en indice de la posición que en tu caso seria el 0:
Aquí unos post que te ayudaran:
http://stackoverflow.com/questions/4998335/linq-query-convert-to-liststring
Como insertar un elemento a una lista:
http://msdn.microsoft.com/en-us/library/sey5k5z4(v=vs.110).aspx
Saludos desde Monterrey, Nuevo León, México!!!
-
Con el siguiente código, yo conseguí algo parecido a lo que necesitas:
Primero el código de una clase que puede estar en un módulo:
Public Class ValueDescriptionPair Public Value As Object Public Description As String Public Sub New(ByVal NewValue As Object, ByVal NewDescription As String) Value = NewValue Description = NewDescription End Sub Public Overrides Function ToString() As String Return Description End Function End Class
Luego la carga del combobox
Private Sub CargarCultivos() Try cboCultivos.Items.Clear() cboCultivos.Items.Add(New ValueDescriptionPair(0, "Seleccione...")) Dim l As New List(Of Cultivo) l = [Global].Business.Conexion.GetCultivos(1) If l.Count <> 0 Then For i As Integer = 0 To l.Count - 1 Dim cultivo As String = l(i).Cultivo Dim codigo As Integer = l(i).Id_Cultivo cboCultivos.Items.Add(New ValueDescriptionPair(codigo, cultivo)) Next End If Catch ex As Exception End Try cboCultivos.SelectedIndex = 0 End Sub
la llamada del dato asociado al texto es:
Dim idCultivo As Integer = CType(cboCultivos.SelectedItem, ValueDescriptionPair).Value
Bien, espero que te sirva este ejemplo.
Saludos
Manuel Luengo Gaete