martes, 10 de noviembre de 2015

Ordenar GridView por Columna

La siguiente solución esta planteada para ordenar los datos de un GridView cuyo DataSource es cualquier lista de objetos o un DataTable, para lo cual utilizaremos un poco de Reflection. xD

Agregar método genérico:
 
Public Sub OrdenarGrilla(Of T)(grid As GridView, lista As List(Of T), campo As String, asc As Boolean)
   If Not String.IsNullOrWhiteSpace(campo) Then
       If asc Then
           lista = lista.OrderBy(Function(l) l.GetType().GetProperty(campo).GetValue(l, Nothing)).ToList()
       Else
           lista = lista.OrderByDescending(Function(l) l.GetType().GetProperty(campo).GetValue(l, Nothing)).ToList()
       End If
   End If
   grid.DataSource = lista
   grid.DataBind()
End Sub

este método puede ser utilizado en caso se tenga un DataTable y no una lista de objetos (por falta de tiempo lo dejo en C#).
 
public void OrdenarGrillaDt( GridView gv, DataTable dt, string campo, bool asc)
        {
            DataView dv = new DataView(dt);
            if (!string.IsNullOrWhiteSpace(campo))
            {
                string sortExp = campo + (asc == true ? " Asc" : " Desc");
                dv.Sort = sortExp;
            }
            dt = dv.ToTable();
            gv.DataSource = dt;
            gv.DataBind();
        }

El cual deberá utilizarse desde el evento Sorting del GridView. Ejemplo:
 
Protected Sub gvDocumentos_Sorting(sender As Object, e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gvDocumentos.Sorting
    OrdenAsc1 = Not OrdenAsc1
    OrdenarGrilla(DirectCast(sender, GridView), listaDocumentos(), e.SortExpression, OrdenAsc1)
End Sub

Donde:
la variable OrdenAsc1 debe ser un ViewState("_OrdenAsc1_") que almacene el valor orden ascendente (true o false).ejemplo:
     Public Property OrdenAsc1() As Boolean
        Get
            If IsNothing(ViewState("_OrdenAsc1_")) Then
                Return True
            End If
            Return ViewState("_OrdenAsc1_")
        End Get
        Set(ByVal value As Boolean)
            ViewState.Add("_OrdenAsc1_", value)
        End Set
    End Property

Nota
El GridView debe de tener las propiedades AllowSorting="true" y SortExpression="colocar lo mismo que se coloca en la propiedad DataField". Ejemplo:
 

    
         
         
    
 

Saludos.

Left Join usando expresiones lambda

A continuación voy a mostrarles como realizar un left join entre 2 listas de objetos (A y B) utilizando expresiones lambda.

Caso 1
Si lo que se quiere es obtener una lista con objetos de A que no se encuentren en B, se debe copiar lo siguiente:


 
Dim lista = listaA.SelectMany(Function(a) listaB.Where(Function(b) b.Codigo = a.Codigo).DefaultIfEmpty().Where(Function(w) IsNothing(w)), Function(a, b) New ObjetoBE With {.Codigo = a.Codigo, .Descripcion = a.Descripcion}).ToList()

Caso 2
Si lo que se quiere es obtener la lista de objetos A, pero diferenciando a los objetos que también están en la lista B. Se debe copiar lo siguiente: 

 
Dim lista = listaA.SelectMany(Function(a) listaB.Where(Function(b) b.Codigo = a.Codigo).DefaultIfEmpty() , Function(a, b) New ObjetoBE With { .Codigo = a.Codigo, .Indicador = If(IsNothing(b),0,1) }).ToList()

Saludos.