ASP.NET MVC Tip #8 – 创建ASP.NET MVC GridView辅助方法

2008-07-13  来源:   浏览次数 2

目前,ASP.NET MVC框架还没有包含任何直接等价于ASP.NET Web Forms GridView控件的东西。每次你需要显示数据时,你都必须编写所有的HTML和内联代码。在这个Tip中,我将向你展示图和为HtmlHelper类添加一个GridView()扩展方法。

扩展方法是由一个类为另一个类添加的方法。你可以使用扩展方法来为现有的类添加更多的功能。在这里,我们将为HtmlHelper类——你在MVC视图页中常用的类——添加一个新的GridView()方法,用于为数据库数据呈现一个HTML表格。在Visual Basic .NET和C#中实现扩展方法有些不同。在Visual Basic .NET中创建扩展方法需要创建一个模块,然后用为模块中的函数添加特性。在C#中创建扩展方法需要创建一个静态类,并使用this关键字声明该静态类重的每个扩展方法的第一个参数。

清单1列出了GridView()扩展方法的代码。

清单1 - GridExtensions.cs

  1. using System;   
  2. using System.Text;   
  3. using System.Collections.Generic;   
  4. using System.Linq;   
  5. using System.Data.Linq.Mapping;   
  6. using System.Data.Linq;   
  7. using System.Web.UI;   
  8. using System.Web.Mvc;   
  9. using System.Web;   
  10.     
  11. namespace Tip8.Helpers   
  12. {   
  13.     public static class GridExtensions   
  14.     {   
  15.         public static string GridView(this HtmlHelper htmlHelper, ITable table)   
  16.         {   
  17.             return GridView(htmlHelper, table, nullnew GridViewOptions());   
  18.         }   
  19.     
  20.         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers)   
  21.         {   
  22.             return GridView(htmlHelper, table, headers, new GridViewOptions());   
  23.         }   
  24.     
  25.         public static string GridView(this HtmlHelper htmlHelper, ITable table, bool includeLinks)   
  26.         {   
  27.             return GridView(htmlHelper, table, null, includeLinks);   
  28.         }   
  29.     
  30.         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers, bool includeLinks)   
  31.         {   
  32.             var options = new GridViewOptions();   
  33.             if (!includeLinks)   
  34.             {   
  35.                 options.ShowViewButton = false;   
  36.                 options.ShowEditButton = false;   
  37.                 options.ShowDeleteButton = false;   
  38.             }   
  39.             return GridView(htmlHelper, table, null, options);   
  40.         }   
  41.     
  42.         public static string GridView(this HtmlHelper htmlHelper, ITable table, string[] headers, GridViewOptions options)   
  43.         {   
  44.             // Show edit column?   
  45.             bool showEditColumn = options.ShowViewButton || options.ShowEditButton || options.ShowDeleteButton;    
  46.     
  47.             // Get identity column name   
  48.             string identityColumnName = GridExtensions.GetIdentityColumnName(table);   
  49.     
  50.             // Get column names and headers   
  51.             var columnNames = GridExtensions.GetColumnNames(table);   
  52.             if (headers == null)   
  53.                 headers = columnNames;   
  54.     
  55.             // Open table   
  56.             var sb = new StringBuilder();   
  57.             sb.AppendLine("<table>");   
  58.     
  59.             // Create Header Row   
  60.             sb.AppendLine("<thead>");   
  61.             sb.AppendLine("<tr>");   
  62.             if (showEditColumn)   
  63.                 sb.Append("<th></th>");   
  64.             foreach (String header in headers)   
  65.                 sb.AppendFormat("<th>{0}</th>", header);   
  66.             sb.AppendLine("</tr>");   
  67.             sb.AppendLine("</thead>");   
  68.     
  69.             // Create Data Rows   
  70.             sb.AppendLine("<tbody>");   
  71.             sb.AppendLine("<tr>");   
  72.             foreach (Object row in table)   
  73.             {   
  74.                 if (showEditColumn)   
  75.                 {   
  76.                     int identityValue = (int)DataBinder.GetPropertyValue(row, identityColumnName);   
  77.                     sb.Append("<td><small>");   
  78.                     if (options.ShowViewButton)   
  79.                     {   
  80.                         sb.Append(htmlHelper.ActionLink(options.ViewButtonText, options.ViewAction, new { Id = identityValue }));   
  81.                         sb.Append(" ");   
  82.                     }   
  83.                     if (options.ShowEditButton)   
  84.                     {   
  85.                         sb.Append(htmlHelper.ActionLink(options.EditButtonText, options.EditAction, new { Id = identityValue }));   
  86.                         sb.Append(" ");   
  87.                     }   
  88.                     if (options.ShowDeleteButton)   
  89.                     {   
  90.                         sb.Append(htmlHelper.ActionLink(options.DeleteButtonText, options.DeleteAction, new { Id = identityValue }));   
  91.                     }   
  92.                     sb.Append("</small></td>");   
  93.                 }   
  94.                 foreach (string columnName in columnNames)   
  95.                 {   
  96.                     string value = DataBinder.GetPropertyValue(row, columnName).ToString();   
  97.                     sb.AppendFormat("<td>{0}</td>", HttpUtility.HtmlEncode(value));   
  98.                 }   
  99.                 sb.AppendLine("</tr>");   
  100.             }   
  101.             sb.AppendLine("</tbody>");   
  102.     
  103.             sb.AppendLine("</table>");   
  104.             return sb.ToString();   
  105.         }   
  106.     
  107.         public static string[] GetColumnNames(ITable table)   
  108.         {   
  109.             return table   
  110.                 .Context   
  111.                 .Mapping   
  112.                 .GetMetaType(table.ElementType)   
  113.                 .PersistentDataMembers.Select(m => m.Name)   
  114.                 .ToArray();   
  115.         }   
  116.     
  117.         public static string GetIdentityColumnName(ITable table)   
  118.         {   
  119.             return table   
  120.                 .Context   
  121.                 .Mapping   
  122.                 .GetMetaType(table.ElementType)   
  123.                 .DBGeneratedIdentityMember   
  124.                 .Name;   
  125.         }   
  126.     }   
  127. }   
  128.    

清单1包含了GridView()方法的多个版本。每个版本的GridView()方法都接受一组不同的参数。例如,第一个版本的GridView()方法接受一个LINQ to SQL表,并呈现来自该表的所有列和行。其它版本的GridView()方法允许你自定义GridView的表头和编辑链接。

清单2中的MVC视图展示了多种调用GridView()方法来展示数据表内容的方式。

清单2 - Index.aspx

  1. <%&#64; Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="Tip8.Views.Home.Index" %>  
  2. <%&#64; Import Namespace="Tip8.Helpers" %>  
  3.     
  4. <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">  
  5.    <h1>Simple Grid</h1>  
  6.    <%= Html.GridView(ViewData.Model) %>  
  7.    <h1>Simple Grid without Links</h1>  
  8.    <%= Html.GridView(ViewData.Model, false) %>  
  9.    <h1>Simple Grid with Custom Headers</h1>  
  10.    <%= Html.GridView(ViewData.Model, new string[] {"AA", "BB", "CC", "DD"} )%>  
  11.    <h1>Simple Grid with Custom Links</h1>  
  12.    <%= Html.GridView(ViewData.Model, null, new GridViewOptions { ViewButtonText = "Look"ShowEditButton=falseShowDeleteButton=false } )%>  
  13. </asp:Content>  
  14.    

清单2中的视图生成了图1所示的HTML页。该页面包含四个单独的数据网格(图中只显示了前三个)。

图1 - Index视图

图1 - Index视图

注意ViewData.Model被传递到GridView()辅助方法中了。ViewData.Model包含了一个LINQ to SQL表。Index视图的code-behind文件为model指定了强类型System.Data.Linq.ITable。model是通过清单3所示的控制器代码传递到视图中的。

清单3 - HomeController.cs

  1. using System;   
  2. using System.Collections.Generic;   
  3. using System.Linq;   
  4. using System.Web;   
  5. using System.Web.Mvc;   
  6. using Tip8.Models;   
  7.     
  8. namespace Tip8.Controllers   
  9. {   
  10.      public class HomeController : Controller   
  11.      {   
  12.          private MovieDataContext _db = new MovieDataContext();   
  13.     
  14.          public ActionResult Index()   
  15.          {   
  16.             return View(_db.Movies);   
  17.          }   
  18.      }   
  19. }   
  20.    

我对该Tip中的这个GridView()辅助方法并不是非常满意。其问题在于使用扩展方法很难自定义GridView中列的外观。例如,我可能希望能够格式化现金和日期列。如果能够有与模板列等价的功能就更好了。在明天的Tip中,我将介绍在使用ASP.NET MVC框架时,一种完全不同的封装GridView的方法。

此处下载源代码:http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip8/Tip8.zip

上一篇:ASP.NET MVC Tip ..    下一篇:嵌入Windows User..

相关主题:

网友评论