ASP.NET MVC Tip #9 – Tạo một GridView View User Control
Trong thủ thuật này, tôi chỉ cho bạn làm thế nào để xây dựng một ASP.NET MVC View User Control chấp nhận các dòng cơ sở dữ liệu và sinh các bản ghi trong một bảng HTML tự động. Ưu điểm của việc sử dụng View User Control là bạn có thể tùy chỉnh vẽ các cột cụ thể. Trong bài trước, tôi đã giải thích ...
Trong thủ thuật này, tôi chỉ cho bạn làm thế nào để xây dựng một ASP.NET MVC View User Control chấp nhận các dòng cơ sở dữ liệu và sinh các bản ghi trong một bảng HTML tự động. Ưu điểm của việc sử dụng View User Control là bạn có thể tùy chỉnh vẽ các cột cụ thể.
Trong bài trước, tôi đã giải thích làm thế nào bạn có thể tạo một helper HTML mới mà sinh ra các bản ghi sơ cơ sở dữ liệu trong một bảng HTML. Nói cách khác, tôi đã giới thiệu một phương pháp để mô phỏng một điều khiển GridView trong ASP.NET MVC. Giờ tôi sẽ chỉ cho bạn một phương pháp thứ hai của mô phỏng một GridView.
Tôi giải thích làm thế nào bạn có thể mô phỏng một điều khiển GridView bằng cách sử dụng một ASP.NET MVC View User Control. Một ASP.NET MVC View User Control cũng tương tự như một ASP.NET User Control với một sự khác biệt quan trọng. Cũng giống như một ASP.NET MVC View, một View User Control có thể chấp nhận dữ liệu strong typed view. Chúng tôi sẽ tạo ra một View User Control chấp nhận dữ liệu View IEnumerable.
GridView View User Control được chứa trong Liệt kê 1. Listing 1 – GridView.ascx (vb)
1: <%@ Control Language="VB" AutoEventWireup="false" CodeBehind="GridView.ascx.vb" Inherits="Tip9.GridView" %> 2: <%@ Import Namespace="System.Reflection" %> 3: 4: <%-- Show the Headers --%> 5: <table class="gridView"> 6: <thead> 7: <tr> 8: <% For Each prop As PropertyInfo In Me.Columns%> 9: <th><%= prop.Name %></th> 10: <% Next%> 11: </tr> 12: </thead> 13: 14: <%-- Show the Rows --%> 15: <tbody> 16: 17: <% For Each row In Me.Rows%> 18: <tr class="<%= Me.FlipCssClass( "item", "alternatingItem") %>"> 19: 20: <%-- Show Each Column --%> 21: <% For Each prop As PropertyInfo In Me.Columns%> 22: <td> 23: <% Dim typeCode = Type.GetTypeCode(prop.PropertyType)%> 24: 25: 26: <%-- String Columns --%> 27: <% If typeCode = typeCode.String Then %> 28: 29: <%= GetColumnValue(row, prop.Name)%> 30: 31: <% End If%> 32: 33: <%-- DateTime Columns --%> 34: <% If typeCode = typeCode.DateTime Then%> 35: 36: <%= GetColumnValue(row, prop.Name, "{0:D}")%> 37: 38: <% End If%> 39: 40: 41: <%-- Decimal Columns --%> 42: <% If typeCode = typeCode.Decimal Then%> 43: 44: <%= GetColumnValue(row, prop.Name, "{0:c}") %> 45: 46: <% End If%> 47: 48: 49: <%-- Boolean Columns --%> 50: <% If typeCode = typeCode.Boolean Then%> 51: <% If Me.GetColumnValue(row, prop.Name) = True Then%> 52: <input type="checkbox" disabled="disabled" checked="checked" /> 53: <% Else%> 54: <input type="checkbox" disabled="disabled" /> 55: <% End If%> 56: <% End If%> 57: 58: 59: <%-- Integer Columns --%> 60: <% If TypeCode = TypeCode.Int32 Then%> 61: 62: <%= GetColumnValue(row, prop.Name)%> 63: 64: <% End If%> 65: 66: </td> 67: <% next %> 68: </tr> 69: <% next %> 70: </tbody> 71: </table> 72: 73:
Listing 1 – GridView.ascx (c#)
1: <%@ Control Language="C#" AutoEventWireup="true" CodeBehind="GridView.ascx.cs" Inherits="Tip9.Views.Home.GridView" %> 2: <%@ Import Namespace="System.Reflection" %> 3: 4: <%-- Show the Headers --%> 5: <table class="gridView"> 6: <thead> 7: <tr> 8: <% foreach (PropertyInfo prop in this.Columns) 9: { %> 10: <th><%= prop.Name %></th> 11: <% } %> 12: </tr> 13: </thead> 14: 15: <%-- Show the Rows --%> 16: <tbody> 17: 18: <% foreach (object row in this.Rows) 19: { %> 20: <tr class="<%= this.FlipCssClass( "item", "alternatingItem") %>"> 21: 22: <%-- Show Each Column --%> 23: <% foreach (PropertyInfo prop in this.Columns) 24: { %> 25: <td> 26: <% var typeCode = Type.GetTypeCode(prop.PropertyType); %> 27: 28: 29: <%-- String Columns --%> 30: <% if (typeCode == TypeCode.String) 31: { %> 32: 33: <%= GetColumnValue(row, prop.Name)%> 34: 35: <% } %> 36: 37: <%-- DateTime Columns --%> 38: <% if (typeCode == TypeCode.DateTime) 39: { %> 40: 41: <%= GetColumnValue(row, prop.Name, "{0:D}")%> 42: 43: <% } %> 44: 45: 46: <%-- Decimal Columns --%> 47: <% if (typeCode == TypeCode.Decimal) 48: { %> 49: 50: <%= GetColumnValue(row, prop.Name, "{0:c}") %> 51: 52: <% } %> 53: 54: 55: <%-- Boolean Columns --%> 56: <% if (typeCode == TypeCode.Boolean) 57: { %> 58: <% if ((bool)(this.GetColumnValue(row, prop.Name))) 59: { %> 60: <input type="checkbox" disabled="disabled" checked="checked" /> 61: <% } 62: else 63: { %> 64: <input type="checkbox" disabled="disabled" /> 65: <% } %> 66: <% } %> 67: 68: 69: <%-- Integer Columns --%> 70: <% if (typeCode == TypeCode.Int32) 71: { %> 72: 73: <%= GetColumnValue(row, prop.Name)%> 74: 75: <% } %> 76: 77: </td> 78: <% } %> 79: </tr> 80: <% } %> 81: </tbody> 82: </table> 83:
Chú ý rằng file GridView.ascx chứa hai vòng lặp. Các lặp vòng lặp đầu tiên thông qua các tiêu đề bảng và lặp vòng lặp thứ hai thông qua các hàng của bảng.
Một loạt các câu lệnh IF được sử dụng để hiển thị một cột cụ thể. Tùy thuộc vào loại cột - Integer, String, số thập phân, DateTime, Boolean - một mẫu khác được sử dụng để hiển thị các giá trị cột. Ví dụ, trong trường hợp của một cột Boolean, một checkbox được sử dụng để hiển thị các giá trị cột (xem hình 1). Bạn có thể, tất nhiên, tùy chỉnh sự xuất hiện của bất kỳ của các cột này bằng cách sửa đổi HTML.
Hình 1 - GridView
Code-behind file cho GridView View User Control được chứa trong Liệt kê 2. Chú ý rằng View User Control có một constructor chung chấp nhận dữ liệu View IEnumerable. Nó cũng cho thấy một số đặc tính properties và methods. Ví dụ, Cột property trả về thông tin về tất cả các cột trong bảng cơ sở dữ liệu (thông tin này được lấy thông qua reflection). Thuộc tính Rows trả về tất cả các hàng bảng cơ sở dữ liệu.
Liệt kê 2 - GridView.ascx.vb (vb)
1: Imports System.Reflection 2: 3: Partial Public Class GridView 4: Inherits System.Web.Mvc.ViewUserControl 5: 6: 7: Protected ReadOnly Property Columns() As PropertyInfo() 8: Get 9: Dim e As IEnumerator = ViewData.Model.GetEnumerator() 10: e.MoveNext() 11: Dim firstRow As Object = e.Current 12: If firstRow Is Nothing Then 13: Throw New Exception("No data passed to GridView User Control.") 14: End If 15: Return firstRow.GetType().GetProperties() 16: End Get 17: End Property 18: 19: Protected ReadOnly Property Rows() As IEnumerable 20: Get 21: Return ViewData.Model 22: End Get 23: End Property 24: 25: 26: Protected Function GetColumnValue(ByVal row As Object, ByVal columnName As String) As Object 27: Return DataBinder.Eval(row, columnName) 28: End Function 29: 30: Protected Function GetColumnValue(ByVal row As Object, ByVal columnName As String, ByVal format As String) As Object 31: Return DataBinder.Eval(row, columnName, format) 32: End Function 33: 34: 35: Dim flip As Boolean = False 36: 37: Protected Function FlipCssClass(ByVal className As String, ByVal alternativeClassName As String) As String 38: flip = Not flip 39: Return IIf(flip, className, alternativeClassName) 40: End Function 41: 42: 43: End Class
Listing 2 – GridView.ascx.cs (c#)
1: using System; 2: using System.Collections; 3: using System.Collections.Generic; 4: using System.Linq; 5: using System.Web; 6: using System.Web.UI; 7: using System.Web.Mvc; 8: using System.Reflection; 9: 10: namespace Tip9.Views.Home 11: { 12: public partial class GridView : System.Web.Mvc.ViewUserControl<IEnumerable> 13: { 14: protected PropertyInfo[] Columns 15: { 16: get 17: { 18: var e = ViewData.Model.GetEnumerator(); 19: e.MoveNext(); 20: object firstRow = e.Current; 21: if (firstRow == null) 22: { 23: throw new Exception("No data passed to GridView User Control."); 24: } 25: return firstRow.GetType().GetProperties(); 26: } 27: } 28: 29: protected IEnumerable Rows 30: { 31: get { return ViewData.Model; } 32: } 33: 34: 35: protected object GetColumnValue(object row, string columnName) 36: { 37: return DataBinder.Eval(row, columnName); 38: } 39: 40: protected object GetColumnValue(object row, string columnName, string format) 41: { 42: return DataBinder.Eval(row, columnName, format); 43: } 44: 45: 46: bool flip = false; 47: protected string FlipCssClass(string className, string alternativeClassName) 48: { 49: flip = !flip; 50: return flip ? className : alternativeClassName; 51: } 52: 53: } 54: }
Bạn có thể sử dụng control GridView trong một View Page bằng cách gọi method Html.RenderUserControl(). View Page trong Liệt kê 3 sinh ra GridView View User Control. Chú ý rằng trang này có chứa một CSS Style Sheet. Style Sheet này được sử dụng để tùy chỉnh sự xuất hiện của bảng được đưa ra bởi các GridView. Ví dụ, các lớp CSS xen kẽ được sử dụng để định dạng xen kẽ hàng GridView.
Liệt kê 3 - index.aspx (vb)
1: <%@ Page Language="VB" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="Tip9.Index" %> 2: 3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4: 5: <html xmlns="http://www.w3.org/1999/xhtml" > 6: <head id="Head1" runat="server"> 7: <title>Index</title> 8: <style type="text/css"> 9: 10: 11: .gridView 12: { 13: border-collapse: collapse; 14: } 15: 16: .gridView th, .gridView td 17: { 18: padding: 5px; 19: } 20: 21: .gridView th 22: { 23: border-bottom: double 3px black; 24: } 25: 26: .gridView td 27: { 28: border-bottom: solid 1px black; 29: } 30: 31: .alternatingItem 32: { 33: background-color: lightgrey; 34: } 35: 36: </style> 37: </head> 38: <body> 39: <div> 40: 41: 42: <%= Html.RenderUserControl("~/Views/Home/GridView.ascx", ViewData.Model) %> 43: 44: </div> 45: </body> 46: </html>
Listing 3 – Index.aspx (C#)
1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Tip9.Views.Home.Index" %> 2: 3: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4: 5: <html xmlns="http://www.w3.org/1999/xhtml" > 6: <head runat="server"> 7: <title>Index</title> 8: <style type="text/css"> 9: 10: 11: .gridView 12: { 13: border-collapse: collapse; 14: } 15: 16: .gridView th, .gridView td 17: { 18: padding: 5px; 19: } 20: 21: .gridView th 22: { 23: border-bottom: double 3px black; 24: } 25: 26: .gridView td 27: { 28: border-bottom: solid 1px black; 29: } 30: 31: .alternatingItem 32: { 33: background-color: lightgrey; 34: } 35: 36: </style> 37: </head> 38: <body> 39: <div> 40: 41: 42: <%= Html.RenderUserControl("~/Views/Home/GridView.ascx", ViewData.Model) %> 43: 44: </div> 45: </body> 46: </html>
Dữ liệu điểm được cung cấp bởi bộ điều khiển trong Liệt kê 4. Bộ điều khiển này sẽ xảy ra để sử dụng một LINQ to SQL truy vấn để lấy dữ liệu cơ sở dữ liệu. Tuy nhiên, GridView là hoàn toàn tương thích với dữ liệu lấy thông qua ADO.NET, NHibernate, hoặc bất cứ điều gì. GridView mong chờ dữ liệu IEnumerable. Chừng nào bạn truyền vào được IEnumerable cho GridView, nó sẽ thật tuyệt vời. Listing 4 -- HomeController.vb (vb)
1: Public Class HomeController 2: Inherits System.Web.Mvc.Controller 3: 4: Private _db As New MovieDataContext() 5: 6: Function Index() 7: Return View(_db.Movies) 8: End Function 9: 10: End Class
Listing 4 -- HomeController.cs (C#)
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using System.Web.Mvc; 6: using Tip9.Models; 7: 8: namespace Tip9.Controllers 9: { 10: public class HomeController : Controller 11: { 12: private MovieDataContext _db = new MovieDataContext(); 13: 14: 15: public ActionResult Index() 16: { 17: return View(_db.Movies); 18: } 19: } 20: }
Tôi thích phương pháp hiển thị một lưới các dữ liệu cơ sở dữ liệu được mô tả trong blog entry này thông qua phương pháp mô tả trong tip bài trước. Không giống như các phương pháp được sử dụng trong tip của ngày hôm qua, phương pháp hiện nay cho phép bạn hoàn toàn tùy chỉnh sự xuất hiện của GridView.
Bạn có thể tải mã cho GridView bằng cách nhấn vào liên kết sau. Tải về bao gồm các mã trong cả C # và các phiên bản VB.NET. Download the Code
Nguồn: https://weblogs.asp.net/stephenwalther/asp-net-mvc-tip-9-create-a-gridview-view-user-control