martes, 9 de junio de 2015

Pasar los valores de un Enum a un BindingSource

Hola a todos,

Hoy os dejo un código que he usado mucho tiempo, pero que estoy seguro que puede ser útil a mucha gente.

Tanto si estamos trabajando con Entity Framework, LinqToSQL o incluso con ADONet, siempre acabamos necesitando ligar unos datos en un combobox u otro control con los datos que tenemos en un Enum.

Mi forma de trabajar es que siempre los controles han de ir conectados a un BindingSource, aunque estos sean valores fijos de un enum, Y por esto os dejo el código utilizado.

Primero, definimos el enum (Lo haré en Visual Basic, pero es fácilmente exportable a C#)

 Public Enum TipoEnum
        MiValor1 = 0
        MiValor2 = 1
        MiValor3 = 2
        MiValor4 = 3
 End Enum


Ahora es cuando me creo una función Shared (Static en c#) donde una vez le paso el tipo del enumerado me devolverá una lista de elementos que podremos asignar al bindingSource.
Pero primero creo la la clase de elementos que usaremos.

Public Class keypairvalueEnum
    Public Property Key As Integer
    Public Property Value As String
 
    Public Sub New(ByVal mykey As IntegerByVal myvalue As String)
        Key = mykey
        Value = myvalue
    End Sub
End Class

Como veis solo creo una clase con dos propiedades que serán mi clave y valor.
Ahora ya puedo crear la función que me devolverá la lista de elementos.

Public Shared Function EnumeradoKeyPairValue(ByVal tipo As TypeAs List(Of keypairvalueEnum)
        Dim ret As New List(Of keypairvalueEnum)
        For Each x In [Enum].GetValues(tipo)
            Dim txt As String = SpaceInCapitalString(x.ToString())
            ret.Add(New keypairvalueEnum(x, txt))
        Next
        Return ret
    End Function
 
    Public Shared Function SpaceInCapitalString(ByVal txt As StringAs String
        Return System.Text.RegularExpressions.Regex.Replace(txt, "[A-Z]"" $0").Trim()        End Function

Veis que hay dos funciones, la primera es la que nos devuelve ese listado que estamos hablando todo el rato, pero la segunda es también importante, ya que nos devuelve los textos formateados correctamente. Que quiero decir con correctamente?,  bueno, que nos interesa que muestre el control, un valor de tipo "MiValor1" o de tipo "Mi Valor1"?. Supongo que os interesará que nos añada un espacio justo antes de cada mayúscula, y de esta manera mostrar no sólo una palabra, sino lo que necesitemos en cada momento... Pues aquí tenéis la forma.

Ya solo falta usar esta función en el formulario:

BindingSource1.DataSource = Enumerados.EnumeradoKeyPairValue(GetType(Enumerados.TipoEnum))

Y ya lo tenemos todo hecho. Espero os sea útil este artículo a todos.
Un saludo,






lunes, 8 de junio de 2015

Entity Framework:No aparecen las entidades relacionadas al hacer binding

Hola a todos,

Esto es algo que se puede encontrar cualquiera, y que prefiero dejaros una solución.

Pongamos el caso.
Hacemos un modelo EF (en mi caso EF 6.1.3) con tablas relacionadas.
Creo un formulario donde pongo un BindingSource y su Datasource le añado el tipo de objeto del Entity Framework.
Acto seguido, añado otro BindingSource para gestionar la otra tabla relacionada, añadimos en el datasource el BindingSource primero que hemos puesto, y desplegamos el dataMember para seleccionar la otra tabla relacionada, y sorpresa!!, no nos muestra nada!!!

Bien, si este es vuestro caso, os aporto una posible solución.

Primero de todo, las referencias.
- Añadir en los nombres importados la referencia de System.Collections.ObjectModel.

Y ahora viene los pasos.
El motivo es que los objetos de la tabla relacionada no aparecen es que es posible que no os lo haya puesto el EF como un lista de tipo observable.

Tenéis que abrir el archivo .tt (según el nombre le hayais puesto al EF).
- Buscáis y remplazáis todas las coincidencias de ICollection por ObservableListSource.
- Luego buscais las coincidencias de HashSet. Encontrareis dos, pues bien, modificar la primera (y solo la primera) también por un ObservableListSource.

Una vez guardéis, os regenerará las clases del entity framework y ya os debería aparecer en el bindingSource.datamember disponible para seleccionar.

Esta solución ha sido sacada a partir de la documentación del Entity framework de esta web (con alguna modificación mía):


https://msdn.microsoft.com/en-us/data/jj682076.aspx  

Double-click on the ProductModel.tt file to open it in the Visual Studio editor
  Find and replace the two occurrences of “ICollection” with “ObservableListSource”. These are located at approximately lines 296 and 484.
  Find and replace the first occurrence of “HashSet” with “ObservableListSource”. This occurrence is located at approximately line 50. Do not replace the second occurrence of HashSet found later in the code.
  Save the ProductModel.tt file. This should cause the code for entities to be regenerated. If the code does not regenerate automatically, then right click on ProductModel.tt and choose “Run Custom Tool”.