[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。
3.
這次拿北風的 Customer 來作為範例:
4.
接下來,來處理分頁的部份,在Controller加入一個PagedList.cs檔案,這邊會透過PagedList<T>類別來處理:
這裡定義了 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 + " ");
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 + " ");
182: 183: linkText = String.Format("{0}", "2");
184: link = helper.ActionLink(linkText, currentAction, new { page = 2, sort = items.SortExpression });
185: writer.Write(link + " ");
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> ", 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 + " ");
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 + " ");
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 + " ");
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 + " ");
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: Index7: </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>
顯示結果:
試煉大會,我們下次見。
如果您有微軟技術開發的問題,可以到MSDN Forum發問。
如果您有微軟IT管理的問題,可以到TechNet Forum發問喔。
