Filter WebGrid With Cascading Dropdownlist Along With Paging in MVC

Introduction

 
I find most developers new to MVC find it difficult to write the kind of code that provides them a kick-start. This is my article on that.
 
For adding paging to a Grid I have used PagedList.MVC.
 
Agenda
  • Creating MVC basic application.
  • Adding an ADO.Net entity model to the application.
  • Adding PagedList.MVC to your application.
  • Adding a Home Controller.
  • Adding a View Model (CustomerView).
  • Adding a View.
  • Binding a dropdown to country.
  • Binding a dropdown to states based on the country using JSON.
  • Finally a binding grid based on country and states.
  • Final output.
Tool been Used
  • Visual Studio 2012.
  • SQL Server and Entity Framework 5.0.
Tables Used for Demo
 
Tables Used for Demo
 
Let's start.
 
Creating MVC basic application
 
For creating the basic application in MVC in Visual Studio IDE select "File" -> "New" -> "Project...". A New Project dialog will be shown. Inside that there is a template list and from that select web and in the project template list select ASP.NET MVC 4 Web Application and name your project DemoGridFilter and click on the OK button.
 
application
 
During the adding of the project, a new dialog will be shown for selecting the Project Template, and inside that select the Basic template.
 
Template
 
After creating the application here is the complete folder view.
 
complete folder view
 
Now that we have created the application, let us start by adding a PagedList.MVC to the application from the NuGet Package Manager.
 
Adding PagedList.MVC in your application
 
For adding PagedList.MVC just right-click on the application then select Manage NuGet Packages.
 
Manage NuGet Packages
 
After selecting Manage NuGet Packages a dialog will be shown.
 
In search type PagedList and then in the search results select the first result PagedList.MVC and click on the Install button.
 
install
 
Here is the view after adding.
 
view after Adding
 
After adding the PagedList.MVC let's add an ADO.NET Entity Data Model.
 
Adding an ADO.NET Entity Data Model to the application (.edmx).
 
Procedure to Add Entity Data Model
 
We will add an ADO.NET Entity Data Model in the Model folder.
  1. For adding, right-click on the Model Folder then select Add then inside that select ADO.NET Entity Data Model.
  2. After selecting, a small dialog will be shown to prompt for a name; I am providing the name DBModel. Then click on the OK button.
  3. After clicking on the OK button a new wizard will be shown with the name Entity Data Model wizard. In that select Generate from Database.
  4. Next, a wizard will be shown for the Connection Properties. Here just enter all the connection-related information for the database that you want to use and then select “Yes include the sensitive data in the connection string”.
  5. Now in the next wizard, it will ask for selecting tables from the database and inside that select Country, States, DeveloperDetails then finally click on the Finish button.
DeveloperDetails
 
After adding the Entity Data Model here is the Designer view of it.
 
Designer view
 
After adding the Entity Data Model here is the complete folder view.
 
Entity Data Model
 
After adding the ADO.NET Entity Data Model let's add a Controller.
 
Adding Myhome Controller
 
For adding the Controller just right-click on the Controller folder then select Add then select Controller. After selecting, a new dialog will be shown with the name Add controller. Here we will name the controller MyhomeController and in the scaffolding option in the template select Empty MVC controller.
 
Controller
 
The Add Controller dialog snapshot is below:
 
add controller
 
After adding the Controller the default Index ActionResult is generated, here is the code.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6.   
  7. namespace DemoGridFilter.Controllers  
  8. {  
  9.     public class MyhomeController : Controller  
  10.     {  
  11.         //  
  12.         // GET: /Myhome/  
  13.   
  14.         public ActionResult Index()  
  15.         {  
  16.             return View();  
  17.         }  
  18.   
  19.     }  
  20. }  
Now let's move forward and add ViewModel with the name SearchModelVM.
 
Adding view Model (SearchModelVM)
 
For adding just right-click on the Model folder then select Add then select Class. A new wizard will be shown asking for a class name. Name it SearchModelVM.cs and click on the Add button.
 
model
 
An empty class is generated.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5.   
  6. namespace DemoGridFilter.Models  
  7. {  
  8.     public class SearchModelVM  
  9.     {  
  10.   
  11.     }  
  12. }  
Now let's add some properties to it.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using PagedList;  
  6.   
  7. namespace DemoGridFilter.Models  
  8. {  
  9.     public class SearchModelVM  
  10.     {  
  11.         public int? Page { getset; }  
  12.         public string DeveloperCount { getset; }  
  13.         public string DevID { getset; }  
  14.         public IPagedList<DeveloperDetail> SearchResults { getset; }  
  15.         public string SearchButton { getset; }  
  16.         public IEnumerable<Country> ListCountry { getset; }  
  17.         public int? SelectedCountryID { getset; }  
  18.         public int? SelectedStateID { getset; }  
  19.     }  
  20. }  
Now in the preceding code, I took Page for maintaining the paging and Developercount and DevID that I will display in the Grid. Then I took an IPagedList for generating the paging control for the Webgrid. The following SearchButton is for letting us know that the user clicked on the search button. The list of Countries is for binding the Dropdownlist. And SelectedCountryID and SelectedStateID are for getting the Dropdownlist's selected value.
 
Adding view
 
To add a view just right-click inside the Index ActionResult. A new dialog will be shown with the name Add View and we have a default view name that is the same as the ActionResult Name (Index). We will not be using the scaffolding template when adding the View.
 
Adding view
 
A blank view is generated and nowhere is the default code that is generated.
  1. @model DemoGridFilter.Models.SearchModelVM  
  2.   
  3. @{  
  4.    ViewBag.Title = "Index";  
  5. }  
  6.   
  7. <h2>Index</h2>  
After adding the View let's add a Bind County and States Dropdownlist on the View.
 
Following I have Added a method (BindCountriesName) for binding Country and this method I will call in the Index [HttpGet] Action Method.
 
The following is the code snippet of the BindCountriesName method:
  1. public void BindCountriesName(SearchModelVM model)  
  2. {  
  3.   
  4.     List<Country> listCountry = new List<Country> {   
  5.         new Country { CountryID = 0 , Name ="Select" }  
  6.     };  
  7.   
  8.     var entities = new AllSampleCodeEntities();  
  9.   
  10.     var Countrieslist = (from ad in entities.Countries select ad).ToList();  
  11.   
  12.     foreach (var item in Countrieslist)  
  13.     {  
  14.         Country objcon = new Country();  
  15.         objcon.CountryID = item.CountryID;  
  16.         objcon.Name = item.Name;  
  17.         listCountry.Add(objcon);  
  18.     }  
  19.   
  20.     model.ListCountry = listCountry;  
  21. }  
After completing the Binding Country we will fill in the states depending on Country and display them in the States dropdownlist. For that, we will use the JSON result that will take the CountryID as input, and depending on that it will get all the states from the database and return a JSON result.
 
Code snippet of GetStates JsonResult
  1. public JsonResult GetStates(string id)  
  2. {  
  3.     if (id == null)  
  4.     {  
  5.         id = "0";  
  6.     }  
  7.   
  8.   
  9.     int CountryID = Convert.ToInt32(id);  
  10.   
  11.   
  12.     AllSampleCodeEntities objord = new AllSampleCodeEntities();  
  13.   
  14.     var states = (from slist in objord.States  
  15.                   where (slist.CountryID == CountryID)  
  16.                   select new { slist.StateID , slist.StateName}).ToList();  
  17.   
  18.     return Json(new SelectList(states, "StateID""StateName"));  
  19. }     
Now after binding both dropdownlists let's configure the action method (Index) to bind the Webgrid.
 
Inside the index action method, I wrote an if the condition that checks that the user has clicked on a button or not. If we had clicked on a button then it will execute the method inside. it will get values from the database depending on the selection of country and state and finally, it will fill in a pagedList Collection with the pageIndex and RecordsPerPage Parameters and then send an entire model to the view.
 
Code snippet of Index ActionResult
  1. const int RecordsPerPage = 1;  
  2.   
  3. public ActionResult Index(SearchModelVM model, FormCollection fc)  
  4. {  
  5.   
  6.     BindCountriesName(model);  
  7.   
  8.   
  9.     if (!string.IsNullOrEmpty(model.SearchButton) || model.Page.HasValue)  
  10.     {  
  11.   
  12.         ViewData["Selectedstate"] = model.SelectedStateID;  
  13.   
  14.         decimal mprice = Convert.ToDecimal(model.SelectedStateID);  
  15.   
  16.         var entities = new AllSampleCodeEntities();  
  17.         var results = entities.DeveloperDetails  
  18.             .Where(p => (p.CountryID == model.SelectedCountryID || model.SelectedCountryID == null) && (p.StateID == mprice || mprice == null))  
  19.             .OrderBy(p => p.CountryID);  
  20.   
  21.         var pageIndex = model.Page ?? 1;  
  22.         model.SearchResults = results.ToPagedList(pageIndex, RecordsPerPage);  
  23.     }  
  24.     return View("Index", model);  
  25. }  
After adding an Action method let's move toward configuring a View. We will now add a Model (SearchModelVM) and a Dropdownlist to the View.
 
Adding Model to View
  1. @model DemoGridFilter.Models.SearchModelVM  
  2. @using PagedList.Mvc  
  3. @{  
  4.     ViewBag.Title = "Index";  
  5.     Layout = "~/Views/Shared/_Layout.cshtml";  
  6. }  
Add a Dropdownlist of County and State to the View as in the following:
  1. <table style="border: 0px; width: 500px;">  
  2.         <tr>  
  3.             <td>  
  4.                 <div class="editor-label">  
  5.                     @Html.Label("Country")  
  6.                 </div>  
  7.                 <div class="editor-field">  
  8.                     @Html.DropDownListFor(model => model.SelectedCountryID, new SelectList(Model.ListCountry, "CountryID""Name"))  
  9.                 </div>  
  10.             </td>  
  11.             <td>  
  12.                 <div class="editor-label">  
  13.                     @Html.Label("States")  
  14.                 </div>  
  15.                 <div class="editor-field">  
  16.                     @Html.DropDownList("SelectedStateID"new SelectList(string.Empty, "StateID""StateName"), "Select State"new { style = "width:250px", @class = "dropdown1" })  
  17.                 </div>  
  18.             </td>  
  19.             <td style="vertical-align: bottom;">  
  20.                 <input name="SearchButton" type="submit" value="Search" />  
  21.             </td>  
  22.         </tr>  
  23.        </table>  
After adding a Dropdownlist list, now let's add a jQuery script for binding the state on a change of the country dropdownlist.
 
Binding dropdown states based on the country using JSON.
 
The following adds a jQuery Ajax script for binding the State dropdownlist.
  1. <link href="~/Content/PagedList.css" rel="stylesheet" />  
  2. <script src="~/Scripts/jquery-1.9.1.min.js"></script>  
  3. <script src="~/Scripts/jquery.validate.min.js"></script>  
  4. <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>  
  5. <script src="~/Scripts/bootstrap.min.js"></script>  
  6. <link href="~/Content/bootstrap.css" rel="stylesheet" />  
  7.   
  8.     $(document).ready(function () {  
  9.         //Dropdownlist Selectedchange event    
  10.         $("#SelectedCountryID").change(function () {  
  11.             $("#SelectedStateID").empty();  
  12.             $.ajax({  
  13.                 type: 'POST',  
  14.                 url: '@Url.Action("GetStates")'// we are calling json method    
  15.                 dataType: 'json',  
  16.                 data: { id: $("#SelectedCountryID").val() },  
  17.                 success: function (states) {  
  18.                     // states contains the JSON formatted list    
  19.                     // of states passed from the controller    
  20.   
  21.                     $("#SelectedStateID").append('<option value="' + "0" + '">' + "Select State" + '</option>');  
  22.                     debugger;  
  23.                     $.each(states, function (i, state) {  
  24.                         $("#SelectedStateID").append('<option value="' + state.Value + '">' + state.Text + '</option>');  
  25.                         // here we are adding option for States    
  26.                     });  
  27.                 },  
  28.                 error: function (ex) {  
  29.                     alert('Failed to retrieve states.' + ex);  
  30.                 }  
  31.             });  
  32.             return false;  
  33.         })  
  34.     });    
  35.     
  36. </script>  
After adding a Dropdownlist and jQuery Ajax script let's run the application and check how your dropdownlist displays.
 
Here is the View of Index.cshtml after rendering on the browser.
 
View of Index
 
We have completed the binding on the dropdownlist. Now let's add a Webgrid and Pagedlist to the view.
 
Adding WebGrid
 
First I have added a Webgrid and then I passed an IPagedList (SearchResults) model to the WebGrid and 1 column (DeveloperCount).
  1. var grid = new WebGrid(Model.SearchResults, defaultSort: "DeveloperCount");  
  2.     @grid.GetHtml(  
  3.         tableStyle: "grid",  
  4.         headerStyle: "gvHeading",  
  5.         rowStyle: "gridrow",  
  6.         alternatingRowStyle: "gridalt",  
  7.         columns: grid.Columns(  
  8.             grid.Column("DeveloperCount""DeveloperCount")  
  9.               
  10.             )  
  11.     )  
Adding PagedListPager
 
Second I have added a PagedListPager and then I passed an IPagedList (SearchResults) model to PagedListPager.
 
Then we need to pass Page, SelectedCountryID, and SelectedStateID parameters to the Controller. For that, we need to Pass the model fields to PagedListPager as given below.
  1. <div class="pagination">  
  2.     @Html.PagedListPager(Model.SearchResults, page => Url.Action("Index"new RouteValueDictionary()   
  3. {  
  4.         { "Page", page },  
  5.         { "SelectedCountryID", Model.SelectedCountryID },  
  6.         { "SelectedStateID", Model.SelectedStateID },  
  7. }),  
  8. PagedListRenderOptions.MinimalWithPageCountText)  
  9. </div>  
After Adding PagedListPager list now let's Maintain state of state Dropdownlist.
 
Finally to maintain the state dropdownlist state I have called a rebindState() function on the $(document).ready method that will check whether or not ViewData["Selectedstate"] is “0” and depending on it will bind the State dropdownlist and then it will make the state dropdownlist selected.
 
Here is the complete code of the snippet of rebindState().
  1. <script type="text/javascript">    
  2.     
  3.         function rebindState() {    
  4.             debugger;    
  5.             if ('@ViewData["Selectedstate"]'!= null) {    
  6.                 $("#SelectedCountryID").val('@Model.SelectedCountryID');    
  7.     
  8.                 $.ajax({    
  9.                     type: 'POST',    
  10.                     url: '@Url.Action("GetStates")',    
  11.                     dataType: 'json',    
  12.                     data: {    
  13.                         id: $("#SelectedCountryID").val()    
  14.                     },    
  15.                     success: function (states) {    
  16.     
  17.                         $.each(states, function (i, state) {    
  18.                             $("#SelectedStateID").append('<option value="' + state.Value + '">' + state.Text + '</option>');  
  19.     
  20.                             if ('@ViewData["Selectedstate"]' != 0) {    
  21.                                 $("#SelectedStateID").val('@ViewData["Selectedstate"]');    
  22.                             }    
  23.                                 
  24.                         });    
  25.                     },    
  26.                     error: function (ex) {    
  27.                         alert('Failed to retrieve states.' + ex);    
  28.                     }    
  29.                 });    
  30.             }    
  31.         }    
  32. </script>  
The following is the completed Home Controller code.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Web.Mvc;  
  6. using DemoGridFilter.Models;  
  7. using PagedList;  
  8.   
  9. namespace DemoGridFilter.Controllers {  
  10.     public class MyhomeController: Controller {  
  11.         const int RecordsPerPage = 1;  
  12.   
  13.         public ActionResult Index(SearchModelVM model, FormCollection fc) {  
  14.   
  15.             BindCountriesName(model);  
  16.   
  17.             if (!string.IsNullOrEmpty(model.SearchButton) || model.Page.HasValue) {  
  18.   
  19.                 ViewData["Selectedstate"] = model.SelectedStateID;  
  20.   
  21.                 decimal mprice = Convert.ToDecimal(model.SelectedStateID);  
  22.   
  23.                 var entities = new AllSampleCodeEntities();  
  24.                 var results = entities.DeveloperDetails  
  25.                     .Where(p => (p.CountryID == model.SelectedCountryID || model.SelectedCountryID == null) && (p.StateID == mprice || mprice == null))  
  26.                     .OrderBy(p => p.CountryID);  
  27.   
  28.                 var pageIndex = model.Page ? ? 1;  
  29.                 model.SearchResults = results.ToPagedList(pageIndex, RecordsPerPage);  
  30.             }  
  31.             return View("Index", model);  
  32.         }  
  33.   
  34.         public void BindCountriesName(SearchModelVM model) {  
  35.   
  36.             List < Country > listCountry = new List < Country > {  
  37.                 new Country { CountryID = 0, Name = "Select" }  
  38.             };  
  39.   
  40.             var entities = new AllSampleCodeEntities();  
  41.   
  42.             var Countrieslist = (from ad in entities.Countries select ad).ToList();  
  43.   
  44.             foreach(var item in Countrieslist) {  
  45.                 Country objcon = new Country();  
  46.                 objcon.CountryID = item.CountryID;  
  47.                 objcon.Name = item.Name;  
  48.                 listCountry.Add(objcon);  
  49.             }  
  50.   
  51.             model.ListCountry = listCountry;  
  52.         }  
  53.   
  54.         public JsonResult GetStates(string id) {  
  55.             if (id == null) {  
  56.                 id = "0";  
  57.             }  
  58.   
  59.             int CountryID = Convert.ToInt32(id);  
  60.   
  61.             AllSampleCodeEntities objord = new AllSampleCodeEntities();  
  62.   
  63.             var states = (from slist in objord.States where(slist.CountryID == CountryID) select new { slist.StateID, slist.StateName }).ToList();  
  64.   
  65.             return Json(new SelectList(states, "StateID""StateName"));  
  66.         }  
  67.   
  68.     }  
The following is the completed Index.cshtml code.
    1. @model DemoGridFilter.Models.SearchModelVM    
    2. @using PagedList.Mvc    
    3. @{    
    4. ViewBag.Title = "Search Developers";    
    5. Layout = "~/Views/Shared/_Layout.cshtml";    
    6. }    
    7. <link href="~/Content/PagedList.css" rel="stylesheet" />    
    8. <script src="~/Scripts/jquery-1.9.1.min.js"></script>    
    9. <script src="~/Scripts/jquery.validate.min.js"></script>    
    10. <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>    
    11. <script src="~/Scripts/bootstrap.min.js"></script>    
    12. <link href="~/Content/bootstrap.css" rel="stylesheet" />    
    13. <style type="text/css">    
    14. .webgrid-table {    
    15.      font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;    
    16.      font-size: 1.2em;    
    17.      width: 100%;    
    18.      display: table;    
    19.      border-collapse: separate;    
    20.      border: solid 1px #98BF21;    
    21.      background-color: white;    
    22. }    
    23.     
    24. .webgrid-table td,    
    25. th {    
    26.      border: 1px solid #98BF21;    
    27.      padding: 3px 7px 2px;    
    28. }    
    29.     
    30. .webgrid-header {    
    31.      background-color: #A7C942;    
    32.      color: #FFFFFF;    
    33.      padding-bottom: 4px;    
    34.      padding-top: 5px;    
    35.      text-align: left;    
    36. }    
    37.     
    38. .webgrid-footer {}    
    39.     
    40. .webgrid-row-style {    
    41.      padding: 3px 7px 2px;    
    42. }    
    43.     
    44. .webgrid-alternating-row {    
    45.      background-color: #EAF2D3;    
    46.      padding: 3px 7px 2px;    
    47. }    
    48. </style>    
    49. <script type="text/javascript">    
    50. $(document).ready(function() {    
    51.      //Dropdownlist Selectedchange event        
    52.      $("#SelectedCountryID").change(function() {    
    53.           $("#SelectedStateID").empty();    
    54.           $.ajax({    
    55.                type: 'POST',    
    56.                url: '@Url.Action("GetStates")'// we are calling json method        
    57.                dataType: 'json',    
    58.                data: { id: $("#SelectedCountryID").val() },    
    59.                success: function(states) {    
    60.                     // states contains the JSON formatted list        
    61.                     // of states passed from the controller        
    62.     
    63.                     $("#SelectedStateID").append('<option value="' + "0" + '">' + "Select State" + '</option>');    
    64.                     debugger;    
    65.                     $.each(states, function(i, state) {    
    66.                          $("#SelectedStateID").append('<option value="' + state.Value + '">' + state.Text + '</option>');    
    67.                          // here we are adding option for States        
    68.                     });    
    69.                },    
    70.                error: function(ex) {    
    71.                     alert('Failed to retrieve states.' + ex);    
    72.                }    
    73.           });    
    74.           return false;    
    75.      })    
    76. });    
    77. </script>    
    78. <script type="text/javascript">    
    79. $(document).ready(function() { rebindState() });    
    80. </script>    
    81. <script type="text/javascript">    
    82. function rebindState() {    
    83.      debugger;    
    84.      if ('@ViewData["Selectedstate"]' != null) {    
    85.           $("#SelectedCountryID").val('@Model.SelectedCountryID');    
    86.     
    87.           $.ajax({    
    88.                type: 'POST',    
    89.                url: '@Url.Action("GetStates")',    
    90.                dataType: 'json',    
    91.                data: {    
    92.                     id: $("#SelectedCountryID").val()    
    93.                },    
    94.                success: function(states) {    
    95.     
    96.                     $.each(states, function(i, state) {    
    97.                          $("#SelectedStateID").append('<option value="' + state.Value + '">' + state.Text + '</option>');    
    98.     
    99.                          if ('@ViewData["Selectedstate"]' != 0) {    
    100.                               $("#SelectedStateID").val('@ViewData["Selectedstate"]');    
    101.                          }    
    102.     
    103.                     });    
    104.                },    
    105.                error: function(ex) {    
    106.                     alert('Failed to retrieve states.' + ex);    
    107.                }    
    108.           });    
    109.      }    
    110. }    
    111. </script>    
    112. <div class="container">    
    113.      @using (Html.BeginForm("Index""Myhome", FormMethod.Get))    
    114.      {    
    115.      @Html.ValidationSummary(false)    
    116.      <div style="border-bottom: 1px solid #bbb">    
    117.           <h2>Search Developers</h2>    
    118.      </div>    
    119.      <table class="table">    
    120.           <tr>    
    121.                <td>    
    122.                     <div class="editor-label">    
    123.                          @Html.Label("Country")    
    124.                     </div>    
    125.                     <div class="editor-field">    
    126.                          @Html.DropDownListFor(model => model.SelectedCountryID, new SelectList(Model.ListCountry, "CountryID""Name"))    
    127.                     </div>    
    128.                </td>    
    129.                <td>    
    130.                     <div class="editor-label">    
    131.                          @Html.Label("States")    
    132.                     </div>    
    133.                     <div class="editor-field">    
    134.                          @Html.DropDownList("SelectedStateID"new SelectList(string.Empty, "StateID""StateName"), "Select State"new { style = "width:250px", @class = "dropdown1" })    
    135.                     </div>    
    136.                </td>    
    137.                <td style="vertical-align: bottom;">    
    138.                     <input name="SearchButton" type="submit" value="Search" />    
    139.                </td>    
    140.           </tr>    
    141.      </table>    
    142.      <div class="table table-bordered .table-striped">    
    143.           @if (Model.SearchResults != null && Model.SearchResults.Count > 0)    
    144.           {    
    145.           var grid = new WebGrid(Model.SearchResults, defaultSort: "DeveloperCount");    
    146.           @grid.GetHtml(    
    147.           tableStyle: "webgrid-table",    
    148.           headerStyle: "webgrid-header",    
    149.           footerStyle: "webgrid-footer",    
    150.           alternatingRowStyle: "webgrid-alternating-row",    
    151.           selectedRowStyle: "webgrid-selected-row",    
    152.           rowStyle: "webgrid-row-style",    
    153.           mode: WebGridPagerModes.All,    
    154.           columns: grid.Columns(    
    155.           grid.Column("DeveloperCount""DeveloperCount")))    
    156.           }    
    157.      </div>    
    158.      if (Model.SearchResults != null && Model.SearchResults.Count > 0)    
    159.      {    
    160.      @Html.PagedListPager(Model.SearchResults, page => Url.Action("Index"new RouteValueDictionary()    
    161.      {    
    162.      { "Page", page },    
    163.      { "SelectedCountryID", Model.SelectedCountryID },    
    164.      { "SelectedStateID", Model.SelectedStateID },    
    165.      }), PagedListRenderOptions.PageNumbersOnly)    
    166.      }    
    167.      }    
    168. </div>   
    The following is the completed WebGrid code.
    1. if (Model.SearchResults != null && Model.SearchResults.Count > 0)  
    2. {  
    3.     var grid = new WebGrid(Model.SearchResults, defaultSort: "DeveloperCount");  
    4. @grid.GetHtml(  
    5.     tableStyle: "grid",  
    6.     headerStyle: "gvHeading",  
    7.     rowStyle: "gridrow",  
    8.     alternatingRowStyle: "gridalt",  
    9.     columns: grid.Columns(  
    10.         grid.Column("DeveloperCount""DeveloperCount"),  
    11.         grid.Column("DevID")  
    12.         )  
    13. )  
    14. <div class="pagination">  
    15.     @Html.PagedListPager(Model.SearchResults, page => Url.Action("Index"new RouteValueDictionary()   
    16. {  
    17.         { "Page", page },  
    18.         { "SelectedCountryID", Model.SelectedCountryID },  
    19.         { "SelectedStateID", Model.SelectedStateID },  
    20. }),  
    21. PagedListRenderOptions.MinimalWithPageCountText)  
    22. </div>  
    23. }  
    Final Output
     
    Here I have selected the country India and the state Andhra Pradesh and clicked on the Search button. Then it brought all the Developer-related data of Andhra Pradesh into the grid and below you can see the Pager list.
     
    The following is the snapshot of the grid displaying with the first record:
     
    grid displaying first record
     
    The following is the snapshot of the grid displaying the second record.
     
    grid displaying second record
     
    Here in the preceding snapshot, you can see we have 2 dropdownlists and after paging, it still maintains the state of the dropdownlist.
     

    Conclusion

     
    Finally, we have completed the learning of the Filter WebGrid with Cascading Dropdownlist along with Paging in MVC.