Creating a Grid Control

This post assumes you already created a new project and configured it properly as shown in the previous post.

 

Before we start using the grid control, let’s add some mock model and repository so we could consume it later to populate the grid.

So first, add the following 2 classes under the Model folder:

Product
  1. public class Product
  2.     {
  3.         public int Id { get; set; }
  4.         public string Name { get; set; }
  5.         public string CompanyName { get; set; }
  6.         public double Price { get; set; }
  7.         public List<Store> Stores { get; set; }
  8.  
  9.         public Product() { this.Stores = new List<Store>(); }
  10.     }

 

Store.cs
public class Store
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public List<Product> Products { get; set; }

    public Store() { this.Products = new List<Product>(); }
}

 

Now, let’s create a repository class that will mock a data access layer.

Create a folder named Repositories, and add the following classes:

ProductRepository.cs
public class ProductRepository
    {
        public List<Product> ListAll()
        {
            List<Product> result = new List<Product>();

            for (int i = 0; i < 20; i++)
            {
                Product p = new Product();
                p.Name = "Product " + i.ToString();
                p.Id = i;
                p.Price = i * 2.5;
                p.CompanyName = "Company " + (i % 5).ToString();
                result.Add(p);
            }

            return result;
        }
    }

 

StoreRepository.cs
public class StoreRepository
    {
        public List<Store> ListAll()
        {
            List<Store> result = new List<Store>();

            for (int i = 0; i < 20; i++)
            {
                Store s = new Store();
                s.Name = "Store " + i.ToString();
                s.Id = i;
                s.Address = "Add " + i.ToString();
                result.Add(s);
            }

            return result;
        }

        public List<Store> GetByProductId(int productId)
        {
            List<Store> result = new List<Store>();

            for (int i = 0; i < 4; i++)
            {
                Store s = new Store();
                s.Name = "Prod Store " + i.ToString();
                s.Id = i;
                result.Add(s);
            }

            return result;
        }
    }

 

Excellent!

Now open the Index.aspx view, and let’s create a products grid:

To enable the Html’s Extension Methods, we need to add an import for the MVC.Controls.Grid namespace before the @Page declaration:

<%@ Import Namespace="MVC.Controls.Grid" %>

 

Now, anywhere inside the <asp.Content> tag, place the following:

<%= Html.Grid(new GridControl()
        .SetName("grid")
        .SetPageSize(10)
        .SetIsAutoSize(true)
        .SetListUrl("Home/List")
        .SetHeight("200")
        .AddColumn(new GridColumnModel("Id").SetAsPrimaryKey())
        .AddColumn(new GridColumnModel("Name"))
        .AddColumn(new GridColumnModel("CompanyName"))
        .AddColumn(new GridColumnModel("Price"))
%>

Lets go over every parameter to better understand what’s going on here:

Grid.SetName – (Mandatory) Each grid control - like any standard html element – must have a unique id.

Grid.SetPgeSize – (Optional) Sets the page size of the grid.

Grid.SetIsAutoSize – (Optional) Set grid’s width can be manually configured, or automagically calculated by size of it’s container.

Grid.SetListUrl – (Optional) The grid data source can be configured in 2 manners: paged using ajax requests to the server, or local data stored in json.
The SetListUrl method tells the grid what action to (ajax-ly) invoke in order to populate the grid. we will discuss later the action parameters, and the local data alternative.

Grid.SetHeight – (Optional) Sets the grid’s height

Grid.AddColumn – (Mandatory) Each grid column is modeled using the GridColumnModel class. we will later discuss the GridColumnModel different attributes but the default most simple configuration requires only one argument which will be used both as a title for the column, as well as a binding path (e.g if the grid is bound to a List<Product>, new GridColumnModel(“Name”) will bind the column to Product.Name).

One of the many columns a grid has, must be declared as Primary key using the GridColumnMode.SetAsPrimaryKey() method, though if you don’t want this column to be shown, you can use the GridColumnModel.SetHidden(true) method.

 

To complete this example, we need to go to the HomeController.cs class and add the List method as linked by Grid.SetListUrl above.
Copy the following code into HomeController.cs

public ActionResult List(int page, int rows, string sidx, string sord)
{
    ProductRepository repository = new ProductRepository();

    List<Product> products = repository.ListAll();

    var model = products.AsQueryable().OrderBy(sidx + " " + sord);
    return Json(model.ToGridData(page, rows, null, "", new[] { "Id", "Name", "CompanyName", "Price" }), JsonRequestBehavior.AllowGet);
}

(Note: you must add using MVC.Controls.Grid; to the using’s in the HomeController.cs for this code to compile)

The grid sends the Controller the following 4 arguments: the page requested, the maximum amount of rows the resulting page can show, and the filtering and ordering parameters defined by the user.

Because the grid requires a special formatting of the data, we use the IQueryable extension method ToGridData to convert our model result to a data structure the grid understands.

Notice that part of the translation from our model to the grid data structure, we define a list of all the properties bound to columns.
This is important to reduce the network overhead of transferring the entire model to the client when we require only a part of it’s information.

 

Enough talking! if you’ve followed the guidelines from this and the previous tutorial, hitting F5 should result in this lovely result:

image

Isn’t she lovely? Winking smile

Last edited Feb 21, 2011 at 8:40 AM by sternr, version 2

Comments

msignoretto Dec 15, 2013 at 3:11 PM 
Why i have this problem
0x800a1391 - Run-time Error JavaScript: '$' is not defined

If there is a handler for this exception, the program may be safely continued.

lawrancee Jul 16, 2013 at 8:41 AM 
Hi All,

Thanks for this. when im running this sample application, im getting following error.

"The parameters dictionary contains a null entry for parameter 'page' of non-nullable type 'System.Int32' for method 'System.Web.Mvc.ActionResult List(Int32, Int32, System.String, System.String)' in 'SampleWithSQl.Controllers.HomeController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
Parameter name: parameters "

and my URl is http://localhost:6238/Home/List

any idea!!!

Thanks in advance,
Lawrence

BillyM Jun 13, 2012 at 6:30 PM 
Is there an example of this using MVC3 / Razor? I added the namespace to web.config but not sure what to do with Html.Grid

anuragpal2 Dec 27, 2011 at 8:08 AM 
Hi,
First of all i thanks to you for posting nice articles over grid Data .
I want to implements delete ,cancle and update button for each rows . but i can't do it
Please let me know the solutions if its possible.

Thanks in advance
Anurag Pal

yvinodreddy Nov 22, 2011 at 5:26 PM 
var model = products.AsQueryable().OrderBy(o => sidx + " " + sord);
return Json(model.ToGridData(page, rows, null, "", new[] { "Id", "Name", "CompanyName", "Price" }), JsonRequestBehavior.AllowGet);

Successfully worked

tazman Nov 3, 2011 at 6:15 PM 
MVC.Controls dll is added as reference, yet I cannot reference it. "failed to import method on ToGridData" Windows 7 / vs 2010 sp1 / mvc 3
return Json(model.ToGridData(page, rows, null, "", new[] { "Id", "Name", "CompanyName", "Price" }), JsonRequestBehavior.AllowGet);

please advise, thanks

AdrianoRR Oct 11, 2011 at 5:41 PM 
I'm having the same problem that @mbabuglia had. And if i try to import System.Linq.Dynamic it says that theres an ambigous call between methods or properties from the System.Linq.Dynamic.DynamicQueryable.OrderBy(string, params object[])

bkominik Jun 6, 2011 at 3:49 PM 
I think you need the dynamic query class. you can get it from the visual studio 2010 examples here: http://archive.msdn.microsoft.com/cs2010samples. Then add:
using System.Linq.Dynamic;;
to your controller

Regards,
Barry

sternr Apr 28, 2011 at 8:59 AM 
Maybe you'r missing a using?
This are the ones I have in the sepcified Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVC.Controls.Examples.Repositories;
using MVC.Controls.Examples.Models;
using MVC.Controls.Grid;

Did it work?

mbabuglia Apr 12, 2011 at 5:34 PM 
Hi,

I am trying to follow your example. I am getting a compilation error on the following line:

var model = products.AsQueryable().OrderBy(sidx + " " + sord);

The error is:
The type arguments for method 'System.Linq.Queryable.OrderBy<TSource,TKey>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource,TKey>>)' cannot be inferred from the usage. Try specifying the type arguments explicitly.

Any help is welcome.
Thanks!
Manuel