Showing posts with label gridview. Show all posts
Showing posts with label gridview. Show all posts

Sunday, December 7, 2014

GridView Custom Paging and Sorting Using LINQ

When displaying large amounts of data it's often best to only display a portion of the data, allowing the user to step through the data ten or so records at a time. Additionally, the end user's experience can be enhanced if they are able to sort the data by one of the columns. Custom paging and sorting is the best solution for this case. You can see the gridview custom paging and sorting using T-SQL post here. In this article I will explain how to populate the ASP.Net GridView control from database using LINQ and how to sort GridView row using its SortExpression property. For this sample to work you will need to download the Microsoft Northwind database here.
GridView Custom Paging and Sorting

First, open Visual Studio 2013 and create one project "WebAppBlog" and then add Class Library "Northwind" as follows:

Inside "Northwind" project, add ADO.NET Entity Data Model as below:

After adding "Northwind.edmx", build the project.

Secondly, create one more Class Library "WebAppBlog.Process".
  

Add Reference "EntityFramework" from  "YourProjectsFolder\packages\EntityFramework.6.0.0\lib\net45\EntityFramework.dll"and "Northwind" from Northwind project as shown below:
Create "Customer.cs" and replace the following code with existing:
using Northwind;
namespace WebAppBlog.Process
{
    public class Customer
    {
        #region Pager
        private int numberOfRecords;
        public int NumberOfRecords
        {
            get { return numberOfRecords; }
            internal set { numberOfRecords = value; IsDirty = true; }
        }

        private int pageSize;
        public int PageSize
        {
            get { return pageSize; }
            internal set { pageSize = value; IsDirty = true; }
        }

        private int currentPageIndex;
        public int CurrentPageIndex
        {
            get { return currentPageIndex; }
            internal set { currentPageIndex = value; IsDirty = true; }
        }
        public string SortExpression { get; private set; }
        public bool IsSortDescending { get; private set; }
        #endregion

        public bool IsDirty { get; set; }
        public List<CustomerDto> CustomerList;
        public void Initialize()
        {
            CurrentPageIndex = 0;
            NumberOfRecords = 0;
            PageSize = 10;
            SortExpression = "CustomerID";
            IsSortDescending = true;

            CustomerList = new List<CustomerDto>();
            IsDirty = false;

        }
        public void Paginate(int pageIndex)
        {
            CurrentPageIndex = pageIndex;
            GetCustomerList();
        }
        public void ResetPageSize(int pageSize)
        {
            PageSize = pageSize;
            CurrentPageIndex = 0;
            GetCustomerList();
        }
        public void Sort(string sortExp)
        {
            IsSortDescending = SortExpression == sortExp ? !IsSortDescending : false;
            SortExpression = sortExp;
            GetCustomerList();
        }
        public void GetCustomerList()
        {
            CustomerList.Clear();
            using (NorthwindEntities context = new NorthwindEntities())
            {
                NumberOfRecords = context.Customers.Count();
                IEnumerable<Northwind.Customer> allCustomerList = context.Customers.ToList();
                IList<Northwind.Customer> customerList = new List<Northwind.Customer>();
               
                if(NumberOfRecords > 0)
                     customerList = GetSortedandPaginatedResult(allCustomerList);

                foreach(var c in customerList)
                {
                    CustomerList.Add(new CustomerDto
                        {
                            CustomerId = c.CustomerID,
                            CompanyName = c.CompanyName,
                            ContactName = c.ContactName,
                            ContactTitle = c.ContactTitle,
                            City = c.City
                        });
                }
            }
        }
        private List<Northwind.Customer> GetSortedandPaginatedResult(IEnumerable<Northwind.Customer> allCustomer)
        {
            var result = new List<Northwind.Customer>();
            if(SortExpression == "CustomerID")
            {
                result = IsSortDescending ? allCustomer.OrderByDescending(o => o.CustomerID).ToList() : 
                    allCustomer.OrderBy(o => o.CustomerID).ToList();
            }
            else if(SortExpression == "ContactName")
            {
                result = IsSortDescending ? allCustomer.OrderByDescending(o => o.ContactName).ToList() : 
                    allCustomer.OrderBy(o => o.ContactName).ToList();
            }
            result = result.Skip(CurrentPageIndex * PageSize).Take(PageSize).ToList();
            return result;
        }
        public class CustomerDto
        {
            public string CustomerId { get; set; }
            public string CompanyName { get; set; }
            public string ContactName { get; set; }
            public string ContactTitle { get; set; }
            public string City { get; set; }
        }

    }
}
After adding "Customer.cs", build the project.
Finally, go to "WebAppBlog" project and add Reference "WebAddBlog.Procecss" and then create "Customer.aspx" page and add the Gridview control as follows:
<asp:GridView ID="gvCustomer" runat="server" AllowCustomPaging="True" AllowPaging="True" 
 AutoGenerateColumns="False" OnPageIndexChanging="gvCustomer_PageIndexChanging" 
 AllowSorting="True" OnSorting="gvCustomer_Sorting">
 <Columns>
  <asp:BoundField DataField="CustomerID" HeaderText="ID" SortExpression="CustomerID" />
  <asp:BoundField DataField="CompanyName" HeaderText="Company Name" />
  <asp:BoundField DataField="ContactName" HeaderText="Contact Name" SortExpression="ContactName" />
  <asp:BoundField DataField="ContactTitle" HeaderText="Contact Title" />
  <asp:BoundField DataField="City" HeaderText="City" />
 </Columns>
 <EmptyDataTemplate>
  <asp:Label ID="Label1" runat="server" Text="No data"></asp:Label>
 </EmptyDataTemplate>
</asp:GridView>
In code-behind, replace the following code with existing one:
public WebAppBlog.Process.Customer Model
{
    get { return Session["ICustomer"] as WebAppBlog.Process.Customer; }
    set { Session["ICustomer"] = value; }
}

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
        InitModel();
}

private void InitModel()
{
    Model = new WebAppBlog.Process.Customer();
    Model.Initialize();
    Model.GetCustomerList();

}
protected void Page_Prerender(object sender, EventArgs e)
{
    BindModel();
}

private void BindModel()
{
    if (Model.IsDirty)
    {
        gvCustomer.VirtualItemCount = Model.NumberOfRecords;
        gvCustomer.PageIndex = Model.CurrentPageIndex;
        gvCustomer.PageSize = Model.PageSize;
        gvCustomer.DataSource = Model.CustomerList;
        gvCustomer.DataBind();

        Model.IsDirty = false;
       
    }
}
protected void gvCustomer_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
    Model.Paginate(e.NewPageIndex);
}

protected void gvCustomer_Sorting(object sender, GridViewSortEventArgs e)
{
    Model.Sort(e.SortExpression);
}
That's it. Thank you! Happy Christmas!

Sunday, May 20, 2012

How to keep checkbox state across over gridview pages

The GridView control is pretty a handy control and is widely used to show the records such as report when building an ASP.NET site. The more you develop with it, the more you reckon how powerful it can be while presenting data. In this article, I will show you how to keep the checkbox state across over pages on the asp.net gridview control as below.
Keeping checkbox state over gridview pages

Sunday, April 29, 2012

How to edit the gridview row data in client side

I always use GridView to show the transactoins or product list in hand without using third party product such as Telerik control. I have to calculate the price or grand total on GridView often. In that sample, I am developing code to show how to access every row and cell from JavaScript, and populate some data operation on these row and cell as below image.
Populating the row data in client side

Saturday, March 24, 2012

Gridview rows blink using JQuery in asp.net

When I'm developing an application with .NET platform, I have a case that is a Gridview row blinking depend on the some column data every one second. I solved it out using JQuery and it is also a simple way by applying "setTimeout" javascript function as below.

Gridview Row Blinking
Gridview Row Blinking
Put the following style sheet to <head> tag.
<style type="text/css">     .bgRow     {         background-color: Green;     }     .norRow     {         background-color: Silver;     } </style>
 Add the following scripts to <head> tag.
<script src="yourUrl/jquery-1.4.1.min.js" type="text/javascript"></script> //it need for JQuery <script type="text/javascript">     function setBG(gridId) {         var id = "#" + gridId;         $(id).find("tr").each(function () {             var css = $(this).attr("class");             if (css != null && css == "bgRow")                 $(this).addClass("norRow").removeClass("bgRow");             else if (css != null && css == "norRow")                 $(this).addClass("bgRow").removeClass("norRow");         });         setTimeout("setBG('" + gridId + "')", 1000); //1000 is equal to one second and call function every one second.     } </script>
Create a Gridview as below. I used "Northwind" db and "Suppliers" table. 
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
    AllowPaging="True" AlternatingRowStyle-Wrap="True" EmptyDataText="There is no data."
    OnRowDataBound="GridView1_RowDataBound" 
    onpageindexchanging="GridView1_PageIndexChanging">
    <Columns>
        <asp:BoundField HeaderText="Supplier ID" DataField="SupplierID" />
        <asp:BoundField HeaderText="Company Name" DataField="CompanyName" />
        <asp:BoundField HeaderText="Address" DataField="Address" />
        <asp:BoundField HeaderText="Country" DataField="Country" />
    </Columns>
</asp:GridView>
Add the below code snippet to code-behind.
protected void Page_Load(object sender, EventArgs e)
{
    try
    {
        if (!Page.IsPostBack)
        {
            using (var context = new NorthwindEntities())
            {
                //Data binding here. I used EF.                 var suppliers = context.Suppliers.ToList();                 GridView1.DataSource = suppliers;                 GridView1.DataBind();             }            }
        //Register javascript and call "setBG" function.         ClientScript.RegisterStartupScript(GetType(), "BG", "setBG('" + GridView1.ClientID + "')", true);     }     catch (Exception ex)     {             } } protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {     if (e.Row.RowType == DataControlRowType.DataRow)     {         string country = DataBinder.Eval(e.Row.DataItem, "Country").ToString();         if(country == "USA")  //set the row background color on condition here.             e.Row.CssClass = "bgRow";     } } protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e) {
    //handle for page index here     GridView1.PageIndex = e.NewPageIndex;     using (var context = new NorthwindEntities())     {         var suppliers = context.Suppliers.ToList();         GridView1.DataSource = suppliers;         GridView1.DataBind();     } }
That's all what you have to do. You'll be glad you did.
Every row has blinking, when they have "Country" column is "USA".

Sunday, December 25, 2011

ASP.NET Gridview with custom paging and sorting.

When displaying large amounts of data it's often best to only display a portion of the data, allowing the user to step through the data ten or so records at a time. Additionally, the end user's experience can be enhanced if they are able to sort the data by one of the columns.
While default paging was easy to implement, it carried with it a performance cost since all records to be paged through were being returned from the database. That is, if the DataGrid was paging through a total of 1,000 records, showing 10 records per page, on each and every page request all 1,000 records would be returned from the database, but only the 10 appropriate ones would be displayed.
Custom paging solved this performance issue by requiring the page developer to tell the DataGrid exactly how many total records were being paged through as well as returning the precise subset of records to display on the page. The following example use ObjectDataSource for DAL and Microsoft.Practices.EnterpriseLibrary.Data.dll (download here) to shorten code.

Gridview with custom paging and sorting.
//Here is server control.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" CellPadding="4"
    AllowPaging="True" AllowSorting="True" AlternatingRowStyle-Wrap="True" 
    DataSourceID="ObjectDataSource1" EmptyDataText="There is no data.">
    <RowStyle BackColor="#EFF3FB" />
    <Columns>
        <asp:BoundField HeaderText="No." DataField="No" />
        <asp:BoundField HeaderText="CustomerID" DataField="CustomerID" SortExpression="CustomerID"/>
        <asp:BoundField HeaderText="CompanyName" DataField="CompanyName" SortExpression="CompanyName" />
        <asp:BoundField HeaderText="ContactName" DataField="ContactName" SortExpression="ContactName" />
        <asp:BoundField HeaderText="ContactTitle" DataField="ContactTitle" SortExpression="ContactTitle" />
    </Columns>
    <AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GridDataPage"
    TypeName="DAL" SelectCountMethod="DataRowCount" 
    SortParameterName="SortExpression" EnablePaging="True">
    <SelectParameters>
        <asp:Parameter Name="maximumRows" Type="Int32" />
        <asp:Parameter Name="startRowIndex" Type="Int32" />
        <asp:Parameter Name="SortExpression" Type="String" />
    </SelectParameters>
</asp:ObjectDataSource>
Here is the connection string in web.config and it use sample "Northwind" db (download here) and "Customers" table.
<connectionStrings>
    <add name="sqlConn" providerName="System.Data.SqlClient"  connectionString="Server='.\SQLEXPRESS';uid='xxxxxx';pwd='xxxxxxxx';Database='Northwind';Pooling=False;"/>
</connectionStrings>
Here is the underlying DAL class for ObjectDataSource.
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;
public class DAL
{
    // Methods
    private static Database getDatabase()
    {
        Database database = null;
        try
        {
            database = DatabaseFactory.CreateDatabase("sqlConn");
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return database;
    }
    public static DataSet GridDataPage(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        if (startRowIndex >= maximumRows)
        {
            startRowIndex++;
        }
        try
        {
            ds = getGridData(maximumRows, startRowIndex, SortExpression);
            if (ds != null && ds.Tables[0].Rows.Count > 0)
            {
                startRowIndex = (startRowIndex > 0) ? startRowIndex : 1;
                for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
                {
                    ds.Tables[0].Rows[i][0] = Convert.ToString((int)(i + startRowIndex));
                }
                HttpContext.Current.Items["rowCount"] = Convert.ToInt32(ds.Tables[1].Rows[0][0].ToString());
                return ds;
            }
            HttpContext.Current.Items["rowCount"] = 0;
        }
        catch (Exception ex)
        {
            //handle exception here.
        }
        return ds;
    }
    public static DataSet getGridData(int maximumRows, int startRowIndex, string SortExpression)
    {
        DataSet ds = new DataSet();
        try
        {
            ds = getDatabase().ExecuteDataSet("GetCustomers", new object[] { maximumRows, startRowIndex, SortExpression });
        }
        catch (Exception ex)
        {
            ds = null;
            //handle exception here.
        }
        return ds;
    }
    public static int DataRowCount(int maximumRows, int startRowIndex, string SortExpression)
    {
        return (int)HttpContext.Current.Items["rowCount"];
    }
}
//Here is transact-sql.
USE [Northwind]
GO
ALTER PROCEDURE [dbo].[GetCustomers]
    @pageSize INT = NULL,
    @pageStart INT = NULL,
    @orderBy nvarchar(200) = NULL
AS
BEGIN

DECLARE @sqlPopulate VARCHAR(2000)
IF @pageSize IS NULL or @pageSize = 0
    SET @pageSize = 10;
IF @pageStart IS NULL
    SET @pageStart = 0;
IF @orderBy IS NULL OR @orderBy = '' 
    SET @orderBy = 'CustomerID DESC';
IF @pageStart = 0
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        + ' FROM dbo.Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) +' CustomerID FROM dbo.Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
        ') ORDER BY ' + @orderBy;
END
ELSE
BEGIN
    SET @sqlPopulate = 'SELECT '' '' AS No, CustomerID, CompanyName, ContactName, ContactTitle ' +
        ' FROM Customers WHERE CustomerID IN '+
        '(SELECT top '+ CAST(@pageSize AS VARCHAR(10)) + ' CustomerID FROM Customers WHERE CustomerID NOT IN '+
            '(SELECT top '+ CAST((@pageStart-1) AS VARCHAR(10)) +' CustomerID FROM Customers ';

    SET @sqlPopulate = @sqlPopulate + ' ORDER BY ' + @orderBy +
            ') ORDER BY ' + @orderBy + ') ORDER BY ' + @orderBy;
END
EXEC(@sqlPopulate)

SET @sqlPopulate = '';
SET @sqlPopulate = 'SELECT COUNT(*) FROM Customers';
EXEC (@sqlPopulate)
END 
Useful link:
Microsoft Enterprise Library

Similar Article

That's it. Enjoy!