0

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 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 alt

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


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.