ASP.NET MVC Tip #9 – Tạo một GridView View User Control
Bài đăng này đã không được cập nhật trong 7 năm
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
All rights reserved