SingingEels : Development Community & Resource

Login

Articles

  • ADO.NET (2)
  • ASP.NET (36)
  • Azure (0)
  • LINQ (5)
  • Security (2)
  • Silverlight (3)
  • SQL (7)
  • Standards (5)
  • WCF (2)

Syndication

  • Articles RSS
  • Blogs RSS

Contribute

  • Our Authors List
  • Member Sign-Up
  • Suggestions Box
Wednesday, March 25, 2009 : 5:16 PM - (2 comments)

Follow up to Self Sorting GridView

Some updates I made to

http://www.singingeels.com/Articles/Self_Sorting_GridView_with_LINQ_Expression_Trees.aspx

to allow Self Paging as well as sorting.

using System;

using System.Collections;

using System.Collections.Generic;

using System.Linq;

using System.Linq.Expressions;

using System.Reflection;

using System.Web.UI;

using System.Web.UI.WebControls;

namespace SingingEels.Web.UI.WebControls

{

// SelfSortingGridView - GridView from www.singingeels.com

// Updated to allow paging as well as sorting.

public class LinqGridView : GridView

{

private string _lastSortExpression;

private SortDirection _lastSortDirection;

protected override void OnSorting(GridViewSortEventArgs e)

{

this.Sorting += new GridViewSortEventHandler(this.SelfSortingGridView_Sorting);

base.OnSorting(e);

}

private void SelfSortingGridView_Sorting(object sender, GridViewSortEventArgs e)

{

this.PageIndex = 0; // Go back to the start of the list on sorting.

if (e.SortExpression == this._lastSortExpression && this._lastSortDirection == SortDirection.Ascending)

{

e.SortDirection = SortDirection.Descending;

}

else

{

e.SortDirection = SortDirection.Ascending;

}

SetupSorting(e.SortExpression, e.SortDirection);

this.DataBind();

this._lastSortExpression = e.SortExpression;

this._lastSortDirection = e.SortDirection;

}

protected override void OnPageIndexChanging(GridViewPageEventArgs eArgs)

{

this.PageIndexChanging += new GridViewPageEventHandler(this.SelfSortingGridView_PageIndexChanging);

base.OnPageIndexChanging(eArgs);

}

private void SelfSortingGridView_PageIndexChanging(object sender, GridViewPageEventArgs eArgs)

{

this.PageIndex = eArgs.NewPageIndex;

if (!string.IsNullOrEmpty(this._lastSortExpression))

SetupSorting(this._lastSortExpression, this._lastSortDirection);

this.DataBind();

}

private void SetupSorting(string sortExpression, SortDirection sortDirection)

{

IEnumerable _data = null;

// This will allow LINQ to SQL to pass the sorting on to the SQL Server itself.

if (this.DataSource is IQueryable)

{

_data = (IQueryable)this.DataSource;

}

else

{

DataSourceView dataView = this.GetData();

if (dataView == null)

{

// No data to sort.

return;

}

dataView.Select(this.SelectArguments, delegate(IEnumerable data)

{

_data = data;

});

if (_data == null)

{

// No data to sort.

return;

}

}

Type dataSourceType = _data.GetType();

Type dataItemType = typeof(object);

if (dataSourceType.HasElementType)

{

dataItemType = dataSourceType.GetElementType();

}

else if (dataSourceType.IsGenericType)

{

dataItemType = dataSourceType.GetGenericArguments()[0];

}

else if (_data is IEnumerable)

{

IEnumerator dataEnumerator = _data.GetEnumerator();

if (dataEnumerator.MoveNext() && dataEnumerator.Current != null)

{

dataItemType = dataEnumerator.Current.GetType();

}

}

var fieldType = dataItemType.GetProperty(sortExpression);

object sorterObject = null;

Type sorterType = null;

// We'll handle things like LINQ to SQL differently by passing the love

// on to the provider.

PropertyInfo property = dataItemType.GetProperty(sortExpression);

if (property != null)

{

sorterType = typeof(GenericSorter<,>).MakeGenericType(dataItemType, property.PropertyType);

sorterObject = Activator.CreateInstance(sorterType);

}

else

{

sorterType = typeof(LateBoundSorter);

sorterObject = Activator.CreateInstance(sorterType);

}

this.DataSource = sorterType.GetMethod("Sort", new Type[] { dataSourceType, typeof(string), typeof(SortDirection) })

.Invoke(sorterObject, new object[] { _data, sortExpression, sortDirection });

}

protected override object SaveControlState()

{

return new object[] { this._lastSortExpression, this._lastSortDirection, base.SaveControlState() };

}

protected override void LoadControlState(object savedState)

{

object[] stateItems = savedState as object[];

if (stateItems != null && stateItems.Length == 3)

{

this._lastSortExpression = (String) stateItems[0];

this._lastSortDirection = (SortDirection) stateItems[1];

base.LoadControlState(stateItems[2]);

}

else

{

base.LoadControlState(savedState);

}

}

}

public class GenericSorter<T, PT>

{

public IEnumerable<T> Sort(IEnumerable source, string sortExpression, SortDirection sortDirection)

{

var param = Expression.Parameter(typeof(T), "item");

var sortLambda = Expression.Lambda<Func<T, PT>>(Expression.Convert(Expression.Property(param, sortExpression), typeof(PT)), param);

if (sortDirection == SortDirection.Ascending)

{

return source.OfType<T>().AsQueryable<T>().OrderBy<T, PT>(sortLambda);

}

else

{

return source.OfType<T>().AsQueryable<T>().OrderByDescending<T, PT>(sortLambda);

}

}

public IEnumerable<T> Sort(IEnumerable<T> source, string sortExpression, SortDirection sortDirection)

{

var param = Expression.Parameter(typeof(T), "item");

var sortLambda = Expression.Lambda<Func<T, PT>>(Expression.Convert(Expression.Property(param, sortExpression), typeof(PT)), param);

if (sortDirection == SortDirection.Ascending)

{

return source.AsQueryable<T>().OrderBy<T, PT>(sortLambda);

}

else

{

return source.AsQueryable<T>().OrderByDescending<T, PT>(sortLambda);

}

}

}

public class LateBoundSorter

{

public IEnumerable Sort(IEnumerable source, string sortExpression, SortDirection sortDirection)

{

if (sortDirection == SortDirection.Ascending)

{

return source.OfType<object>().OrderBy(item =>

this.GetPropertyValue(item, sortExpression));

}

else

{

return source.OfType<object>().OrderByDescending(item =>

this.GetPropertyValue(item, sortExpression));

}

}

private object GetPropertyValue(object item, string propertyName)

{

return item.GetType().GetProperty(propertyName).GetValue(item, null);

}

}

}

Blog Archives

  • March 2009 - (1)

Related Ads

SingingEels.com as of Feb 04 2012 - 12:37:42 AM - (0.03125)