[VS2010 Online]初窺ASP.NET MVC(4) - GridView控制項的使用

[VS2010 Online]初窺ASP.NET MVC(4) - GridView控制項的使用

在 [初窺ASP.NET MVC (3) - 控制項的使用] 我們談了蠻多的控制項,但是眼尖的你有沒有發現到,

過去我們在 ASP.NET 常用來顯示多筆資料的 GridView 老兄怎麼沒有登場呢?

 

筆者接下來就來介紹如何使用GridView:

1.

首先,建立一個全新的 ASP.NET MVC Web Apllication專案。

 

2.

在專案中新增一個 LINQ to SQL 的物件,這邊我們把它命名為Northwind.dbml。

image

 

3.

這次拿北風的 Customer 來作為範例:

image

 

4.

接下來,來處理分頁的部份,在Controller加入一個PagedList.cs檔案,這邊會透過PagedList<T>類別來處理:

image

 

這裡定義了 PageIndex、PageSize、TotalItemCount、TotalPageCount、SortExpression

以及 IdentityColumnName 屬性。分別用來處理當前頁面、每頁數量、資料列總數、頁面總數、

排序以及資料的 PK。

 

5.

然後針對LINQ的查詢以及回傳的List型別,我們建立一個PageLinqExtensions的類別,其中包含了三個擴充方法

(extension method),這三個擴充方法分別是3~12行的,提供 pageIndex、pageSize輸入;14~23行,提供

pageIndex、pageSize 以及 identityColumnName 輸入;25~41行,其中包含 pageIndex、pageSize、

identityColumnName以及排序所需的字串:

   1: public static class PageLinqExtensions
   2:     {
   3:         public static PagedList<T> ToPagedList<T>
   4:             (
   5:                 this IQueryable<T> allItems,
   6:                 int? pageIndex,
   7:                 int pageSize
   8:             )
   9:         {
  10:             return ToPagedList<T>(allItems, pageIndex, pageSize,null, String.Empty);
  11:  
  12:         }
  13:  
  14:         public static PagedList<T> ToPagedList<T>
  15:             (
  16:                 this IQueryable<T> allItems,
  17:                 int? pageIndex,
  18:                 int pageSize, 
  19:                 string identityColumnName        
  20:             )
  21:         {
  22:             return ToPagedList<T>(allItems, pageIndex, pageSize, identityColumnName, String.Empty);
  23:         }
  24:  
  25:         public static PagedList<T> ToPagedList<T>
  26:                (
  27:                    this IQueryable<T> allItems,
  28:                    int? pageIndex,
  29:                    int pageSize,
  30:                    string identityColumnName,
  31:                    string sort
  32:                )
  33:         {
  34:             var truePageIndex = pageIndex ?? 0;
  35:             var itemIndex = truePageIndex * pageSize;
  36:             var pageOfItems = allItems.Skip(itemIndex).Take(pageSize);
  37:             var totalItemCount = allItems.Count();
  38:  
  39:             return new PagedList<T>(pageOfItems, truePageIndex, pageSize, totalItemCount,identityColumnName, sort);
  40:  
  41:         }
  42:     
  43:     }

 

 

6.

接下來,處理GridView的功能設定,我們建立一個 GridViewOption.cs 檔案,然後在類別中定義顯示編輯、刪除

功能的相關屬性,像是按鈕的內容、是否顯示以及對應的Action:

   1: public class GridViewOption
   2:    {
   3:        private bool  showEditButton = true;
   4:        private bool  showDeleteButton = true;
   5:  
   6:        private string  editButtonText = "Edit";
   7:        private string  deleteButtonText = "Delete";
   8:  
   9:        private string  editAction = "Edit";
  10:        private string  deleteAction = "Delete";
  11:  
  12:        private string[] columns;
  13:  
  14:        public string[] Columns
  15:        {
  16:            get { return columns  ; }
  17:            set { columns= value; }
  18:        }
  19:  
  20:  
  21:        public bool ShowEditButton
  22:        {
  23:            get { return  showEditButton; }
  24:            set {  showEditButton = value; }
  25:        }
  26:  
  27:        public bool ShowDeleteButton
  28:        {
  29:            get { return  showDeleteButton; }
  30:            set {  showDeleteButton = value; }
  31:        }
  32:  
  33:  
  34:        public string EditButtonText
  35:        {
  36:            get { return  editButtonText; }
  37:            set {  editButtonText = value; }
  38:        }
  39:  
  40:        public string DeleteButtonText
  41:        {
  42:            get { return  deleteButtonText; }
  43:            set {  deleteButtonText = value; }
  44:        }
  45:  
  46:  
  47:        public string EditAction
  48:        {
  49:            get { return  editAction; }
  50:            set {  editAction = value; }
  51:        }
  52:  
  53:        public string DeleteAction
  54:        {
  55:            get { return  deleteAction; }
  56:            set {  deleteAction = value; }
  57:        }
  58:    }

 

7.

接下來,我們來定義 GridView 的顯示內容,先新增一個 GridViewHelper 類別,然後在裡面定義三個擴充方法,

這三個方法會去處理Model、要顯示的內容以及編輯、刪除按鈕。程式碼可以參考如下:

   1: public static class GridViewHelper
   2:     {
   3:         public static string GridView<T>(this HtmlHelper helper)
   4:         {
   5:             return GridView<T>(helper, null, null,new GridViewOption());
   6:         }
   7:  
   8:         public static string GridView<T>(this HtmlHelper helper, object data)
   9:         {
  10:             return GridView<T>(helper, data, null,new GridViewOption());
  11:         }
  12:  
  13:         public static string GridView<T>(this HtmlHelper helper, object data, string[] columns, GridViewOption options)
  14:         {
  15:       
  16:             // Get items   
  17:             var items = (IEnumerable<T>)data;
  18:             if (items == null)
  19:                 items = (IEnumerable<T>)helper.ViewData.Model;  
  20:  
  21:             // Get column names   
  22:             if (columns == null)
  23:                 columns = typeof(T).GetProperties().Select(p => p.Name).ToArray();
  24:  
  25:             // Create HtmlTextWriter   
  26:             var writer = new HtmlTextWriter(new StringWriter());
  27:  
  28:             // Open table tag   
  29:             writer.RenderBeginTag(HtmlTextWriterTag.Table);
  30:  
  31:             // Render table header   
  32:             writer.RenderBeginTag(HtmlTextWriterTag.Thead);
  33:             RenderHeader(helper, writer, columns, options);
  34:             writer.RenderEndTag();
  35:  
  36:             string identityColumnName= ((PagedList<T>)items).IdentityColumnName ;
  37:  
  38:             // Render table body   
  39:             writer.RenderBeginTag(HtmlTextWriterTag.Tbody);
  40:             foreach (var item in items)
  41:                 RenderRow<T>(helper, writer, columns, item, identityColumnName, options);
  42:             writer.RenderEndTag();
  43:  
  44:            
  45:             RenderPagerRow<T>(helper, writer, (PagedList<T>)items, columns.Count());
  46:  
  47:             // Close table tag   
  48:             writer.RenderEndTag();
  49:  
  50:             // Return the string   
  51:             return writer.InnerWriter.ToString();
  52:         }
  53:  
  54:  
  55:         private static void RenderHeader(HtmlHelper helper, HtmlTextWriter writer, string[] columns, GridViewOption options)
  56:         {
  57:             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
  58:             int i = 0;
  59:  
  60:             foreach (var columnName in columns)
  61:             {
  62:                 writer.RenderBeginTag(HtmlTextWriterTag.Th);
  63:                 var currentAction = (string)helper.ViewContext.RouteData.Values["action"];
  64:  
  65:                 string link=null;
  66:                 if (options.Columns == null)
  67:                 
  68:                     link = helper.ActionLink(columnName, currentAction, new { sort = columnName }).ToHtmlString();
  69:                 
  70:                 else
  71:                 {
  72:                   
  73:                     link = helper.ActionLink(options.Columns[i], currentAction, new { sort = columnName }).ToHtmlString();
  74:                     i++;
  75:                 }
  76:                 writer.Write(link);
  77:                 writer.RenderEndTag();
  78:               
  79:  
  80:                 
  81:             }
  82:             // Show edit column?
  83:             bool showEditColumn = options.ShowEditButton || options.ShowDeleteButton;
  84:  
  85:             if (showEditColumn)
  86:             { 
  87:               writer.RenderBeginTag(HtmlTextWriterTag.Th);
  88:               writer.Write(helper.Encode(""));
  89:               writer.RenderEndTag();
  90:             }            
  91:             writer.RenderEndTag();
  92:         }
  93:  
  94:         private static void RenderRow<T>(HtmlHelper helper, HtmlTextWriter writer, string[] columns, T item ,string identityColumnName, GridViewOption options)
  95:         {
  96:             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
  97:             foreach (var columnName in columns)
  98:             {
  99:                 writer.RenderBeginTag(HtmlTextWriterTag.Td);
 100:                 var value = typeof(T).GetProperty(columnName).GetValue(item, null) ?? String.Empty;
 101:                 writer.Write(helper.Encode(value.ToString()));   
 102:                 writer.RenderEndTag();
 103:             }
 104:  
 105:             // Show edit column?
 106:             bool showEditColumn = options.ShowEditButton || options.ShowDeleteButton;
 107:  
 108:             if (showEditColumn)
 109:             { 
 110:               var identityVaule = typeof(T).GetProperty(identityColumnName).GetValue(item, null);
 111:               writer.RenderBeginTag(HtmlTextWriterTag.Td);
 112:  
 113:                 if ( options.ShowEditButton)
 114:                 {
 115:                    var link = helper.ActionLink(options.EditButtonText,options.EditAction , new { id =identityVaule });
 116:                    writer.Write(link);
 117:                    writer.Write(" ");  
 118:                 }
 119:  
 120:                 if (options.ShowDeleteButton )
 121:                 { 
 122:                    var link = helper.ActionLink(options.DeleteButtonText, options.DeleteAction , new { id = identityVaule });
 123:                    writer.Write(link);            
 124:                 }
 125:                 
 126:               writer.RenderEndTag();
 127:             }
 128:  
 129:             writer.RenderEndTag();
 130:         }
 131:  
 132:         private static void RenderPagerRow<T>(HtmlHelper helper, HtmlTextWriter writer, PagedList<T> items, int columnCount)
 133:         {
 134:             int nrOfPagesToDisplay = 10;
 135:  
 136:             // Don't show paging UI for only 1 page   
 137:             if (items.TotalPageCount == 1)
 138:                 return;
 139:  
 140:             // Render page numbers   
 141:             writer.RenderBeginTag(HtmlTextWriterTag.Tr);
 142:             writer.AddAttribute(HtmlTextWriterAttribute.Colspan, columnCount.ToString());
 143:             writer.RenderBeginTag(HtmlTextWriterTag.Td);
 144:             var currentAction = (string)helper.ViewContext.RouteData.Values["action"];
 145:  
 146:             if (items.PageIndex >= 1)
 147:             {
 148:                 var linkText = String.Format("{0}", "<<<");
 149:                 var link = helper.ActionLink(linkText, currentAction, new { page = items.PageIndex, sort = items.SortExpression });
 150:                 writer.Write(link + "&nbsp;");
 151:             }
 152:  
 153:             int start = 0;
 154:             int end = items.TotalPageCount;
 155:  
 156:             if (items.TotalPageCount > nrOfPagesToDisplay)
 157:             {
 158:                 int middle = (int)Math.Ceiling(nrOfPagesToDisplay / 2d) - 1;
 159:                 int below = (items.PageIndex - middle);
 160:                 int above = (items.PageIndex + middle);
 161:  
 162:                 if (below < 4)
 163:                 {
 164:                     above = nrOfPagesToDisplay;
 165:                     below = 0;
 166:                 }
 167:                 else if (above > (items.TotalPageCount - 4))
 168:                 {
 169:                     above = items.TotalPageCount;
 170:                     below = (items.TotalPageCount - nrOfPagesToDisplay);
 171:                 }
 172:  
 173:                 start = below;
 174:                 end = above;
 175:             }
 176:  
 177:             if (start > 3)
 178:             {
 179:                 var linkText = String.Format("{0}", "1");
 180:                 var link = helper.ActionLink(linkText, currentAction, new { page = 1, sort = items.SortExpression });
 181:                 writer.Write(link + "&nbsp;");
 182:  
 183:                 linkText = String.Format("{0}", "2");
 184:                 link = helper.ActionLink(linkText, currentAction, new { page = 2, sort = items.SortExpression });
 185:                 writer.Write(link + "&nbsp;");
 186:  
 187:                 writer.Write(String.Format("{0}", "..."));
 188:             }
 189:  
 190:             for (var i = start; i < end; i++)
 191:             {
 192:  
 193:                 if (i == items.PageIndex)
 194:                 {
 195:                     writer.Write(String.Format("<strong>{0}</strong>&nbsp;", i + 1));
 196:                 }
 197:                 else
 198:                 {
 199:                     var linkText = String.Format("{0}", i + 1);
 200:                     var link = helper.ActionLink(linkText, currentAction, new { page = i + 1, sort = items.SortExpression });
 201:                     writer.Write(link + "&nbsp;");
 202:                 }
 203:  
 204:             }
 205:  
 206:             if (end < (items.TotalPageCount - 3))
 207:             {
 208:                 writer.Write(String.Format("{0}", "..."));
 209:  
 210:                 var linkText = String.Format("{0}", items.TotalPageCount - 1);
 211:                 var link = helper.ActionLink(linkText, currentAction, new { page = items.TotalPageCount - 1, sort = items.SortExpression });
 212:                 writer.Write(link + "&nbsp;");
 213:  
 214:                 linkText = String.Format("{0}", items.TotalPageCount);
 215:                 link = helper.ActionLink(linkText, currentAction, new { page = items.TotalPageCount, sort = items.SortExpression });
 216:                 writer.Write(link + "&nbsp;");
 217:             }
 218:  
 219:  
 220:             if (items.PageIndex + 2 <= items.TotalPageCount)
 221:             {
 222:  
 223:                 var linkText = String.Format("{0}", ">>>");
 224:                 var link = helper.ActionLink(linkText, currentAction, new { page = items.PageIndex + 2, sort = items.SortExpression });
 225:                 writer.Write(link + "&nbsp;");
 226:             }
 227:  
 228:             writer.RenderEndTag();
 229:             writer.RenderEndTag();
 230:         }
 231:  
 232:     }

 

這段程式碼分成四個部份,3~52行處理Model、顯示內容以及編輯刪除的設定。55~92行處理GridView的header。

94~130行處理GridView的內容。第四部份則是處理頁數的顯示。

 

8.

HomeController如下設定:

   1: public class HomeController : Controller
   2:     {
   3:         NorthwindDataContext db = new NorthwindDataContext();
   4:  
   5:         public ActionResult Index(string sort, int? page)
   6:         {
   7:             ViewData["Message"] = "GridView!!";
   8:  
   9:             page = page ?? 0;
  10:             if (page >= 1) page = page - 1;
  11:  
  12:             if (sort != null)
  13:             {
  14:                 var model1 = (from c in db.Customers
  15:                               select c)
  16:                               .OrderBy(sort)
  17:                               .ToPagedList(page, 5, "CustomerID", sort);
  18:                 return View(model1);
  19:             }
  20:             else
  21:             {
  22:                 var model2 = (from c in db.Customers
  23:                               select c).ToPagedList(page, 5, "CustomerID");
  24:                 return View(model2);
  25:  
  26:             }
  27:                         
  28:         }
 

 

Index.aspx設定:

   1: <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<PagedList<Customer>>" %>
   2: <%@ Import Namespace ="MvcApplication3.Models" %>
   3: <%@ Import Namespace ="Test" %>
   4:  
   5: <asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
   6:     Index
   7: </asp:Content>
   8:  
   9: <asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
  10:  
  11:    <h2><%
   1: = Html.Encode(ViewData["Message"]) 
%></h2>
  12:     <p>Show GridView</p>
  13:     
  14:     <%
   1:  =Html.GridView<Customer>(Model, new string[] { "CustomerID", "CompanyName", "ContactName", "Address", "City" },
   2:                         new GridViewOption() )
   3:  
   4:         
%>
  15: </asp:Content>
 

 

顯示結果:

image

 

 

試煉大會,我們下次見。

 

 

 

 

 

如果您有微軟技術開發的問題,可以到MSDN Forum發問。

如果您有微軟IT管理的問題,可以到TechNet Forum發問喔。