65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET MVC 中的 WebGrid

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.95/5 (13投票s)

2015年10月15日

CPOL

6分钟阅读

viewsIcon

80801

downloadIcon

1679

ASP.NET MVC 中的 WebGrid

引言

在本文中,我们将讨论 ASP.NET MVC 中的 WebGrid。作为一名 ASP.NET Webforms 开发者,我们都知道 DataGrid 服务器控件(gridview/datagrid),当我们想向用户显示记录时,我们通常会使用它们。所以我们现在知道,我们有 ASP.NET WebForms 和 ASP.NET MVC。在 ASP.NET MVC 中,没有像 ASP.NET Web Forms 那样的服务器控件(工具箱)。但微软能够理解开发者在制作表格、循环以及使用 jQuery 处理表格方面长期以来付出的艰辛,因此他们为我们提供了 WebGrid 类。那么,为什么还要等待呢?赶紧拿起你的 PC/笔记本电脑,启动你的 Visual Studio,让我们开始吧。

简单示例

基本上,网格包含记录列表,即 MVC 中的集合,需要强类型列表等。所以在这里,我们将把记录显示在 WEB 网格中。

步骤 1:创建新的 MVC 项目

步骤 2:选择 MVC

步骤 3:添加一个新的空 MVC 控制器

根据你的理解命名它,我在这里将其命名为 Meeting,因为这个控制器将处理 Meeting 的请求。

下面,我将显示如下所示的数据库表中 Meeting 的详细记录:

现在我们将创建我们的 Model 类,其中包含与上面显示的表相同的属性。

步骤 4:创建 Meeting 类

现在,我们将如下所示声明类的属性,我们将使用 Entity Framework 从表中检索数据,为了做到这一点,我们需要设置 Entity Framework 所需的关键,如下所示:

using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
namespace WebGridNew1.Models
{
    public class Meeting
    {
        [Key]
        public int MeetingId { get; set; }
        public string MeetingName { get; set; }
        public string Format { get; set; }
        public string Location { get; set; }
    }
}

我们将使用 Entity Framework 从 DB Schema 中检索数据。为了做到这一点,我们需要从 NuGet 包下载 Entity Framework。

安装它。

现在,我们将添加另一个类,并将其命名为 DataAccessLayer.cs。这个类将包含所有与表和 DbContext 的映射代码。

步骤 5:添加 DAL 类并添加如下所示的属性

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebGridNew1.Models
{
    public class DataAccessLayer:DbContext
    {
        public DbSet<Meeting> MeetingMaster { get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
      modelBuilder.Entity<Meeting>().ToTable("tblMeetingMaster");
            base.OnModelCreating(modelBuilder);
        }
    }
}

编写映射代码,Dbset MeetingMaster 将返回 Meetings 的集合,modelBuilder.entity 将映射模型和数据库架构表。

现在,我们将添加 web config 文件并添加连接字符串。

步骤 6:转到服务器资源管理器并添加新连接

选择你的数据库

右键单击数据连接,然后转到属性,复制连接字符串并将其添加到 Web.Config 文件中

<connectionStrings>
    <add name="DataAccessLayer" 
connectionString="Data Source=.;Initial Catalog=Demos;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

确保你的 <add name="_"> 名称与你的数据访问层类名相同。

现在,我们将添加另一个名为 ViewModel 的类,ViewModel 是我们模型和视图之间的层类型,它将与视图和模型进行通信,并且将包含视图逻辑,基本上 ViewModel 帮助我们维护视图和控制器之间的关注点分离。

所以我们要做的,这里是项目的实际主题:我们的 DAL 层将从表中获取数据,这些数据将被 ViewModel 使用并分配给列表,然后列表对象将被发送到 ViewModel 类的强类型视图,在那里它将数据显示在 WebGrid 中。为了检查 meeting 列表是否为 null,我们在 ViewModel 中添加了一个名为 Status 的属性,它将检查 Customers 列表是否为 null,如果为 null,则在视图中,我们将隐藏 WebGrid,否则将显示它。

下面是 MeetingViewModel

using System.Web;
using WebGridNew1.Models;
namespace WebGridNew1.Models
{
    public class MeetingVM
    {
        public Meeting  MeetingObj { get; set; }//contains single meeting details
        public List<Meeting> MeetingsObj { get; set; }//list of meeting
        public string  Status { get; set; }//This will help us to handle the view logic
    }
}

现在在 Controller 中,我们将创建 DAL 类的对象并从数据库检索所有记录,然后将 ViewModel 对象返回给视图。

using System.Web.Mvc;
using WebGridNew1.Models;
namespace WebGridNew1.Controllers
{
    public class MeetingController : Controller
    {
        public ActionResult Index()
        {
            DataAccessLayer objDAL = new DataAccessLayer();
            MeetingVM objMeetingVM = new MeetingVM();
            objMeetingVM.MeetingsObj = new List<Meeting>();
            objMeetingVM.MeetingsObj = objDAL.MeetingMaster.ToList<Meeting>();
            return View(objMeetingVM);
        }
    }
}

添加一个名为 index 的视图,并将其创建为 MeetingViewModel 类的强类型视图。

步骤 5:添加 Index 视图

现在复制以下代码并复制它

@model WebGridNew1.Models.MeetingVM
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div style="display:'@Model.Status'">
        @{
            WebGrid objWebGrid = new WebGrid(Model.MeetingsObj);
        }
        @objWebGrid.GetHtml()
    </div>
</body>
</html>

我们可以看到 WebGrid 是一个类,它包含在 System.Web.Helpers.WebGrid 中,在这里我们创建了 WebGrid 类的对象并将我们的 Meeting 模型列表分配给它。

@objWebGrid.GetHtml();

此函数返回 HTML 标记,用于渲染我们上面创建的对象,并指定分页。

现在,我们将运行我们的程序,看看 WebGrid 如何渲染模型并显示模型数据,默认情况下 WebGrid 中的分页和排序都是 true 的,并且可以禁用。

现在我们将继续为我们的 WebGrid 进行一些样式设置。为了设置表头样式,我们需要在 head 部分创建 <style>,我选择每页显示 5 行,并定义如下所示的类及其相应的样式。

<div style="text-align:center;display:@Model.Status">
        @{
            WebGrid objWebGrid = new WebGrid(Model.MeetingsObj,rowsPerPage:5,canPage:true);
        }
        @objWebGrid.GetHtml(
       tableStyle:"Grid-table",
       headerStyle:"Grid-Header",
       alternatingRowStyle:"Grid-alt",
       selectedRowStyle:"Grid-selected",
       rowStyle: "Grid-rowstyle",
       mode: WebGridPagerModes.All //Specifies flags that describe the methods 
       // that are provided for moving between the pages of a WebGrid instance. 
       // source msdn.microsoft.com
  )
</div>

现在我们将传递一个空的 null 模型,并尝试在视图模型中处理它,所以现在我将发送一个空模型,并在 ViewModel 类中处理视图逻辑,如下所示。

namespace WebGridNew1.Models
{
    public class MeetingVM
    {
        public Meeting  MeetingObj { get; set; }//contains single meeting details
        public List<Meeting> MeetingsObj { get; set; }//list of meeting
        public string  Status {
            get
            {
                if (MeetingsObj.Count > 0)
                {
                    return "block";
                }
                else
              { return "none";  }
            }
                }//This will help us to handle the view logic
    }
}

在控制器中

public ActionResult Index()
        {
            DataAccessLayer objDAL = new DataAccessLayer();
            MeetingVM objMeetingVM = new MeetingVM();
            objMeetingVM.MeetingsObj = new List<Meeting>();
            //objMeetingVM.MeetingsObj = objDAL.MeetingMaster.ToList<Meeting>();
    // commented the code for records retrieval and returning empty object
            return View(objMeetingVM);
        }

现在让我们一步一步地看看它是如何工作的,我在 status 属性以及 controller 中插入了一个断点。

这里,我们创建一个 null 对象并将返回它

现在当我们在视图中想要获取 Status 属性的值时,它将检查状态属性的值,如上所示

这里 status 将返回,所以 div 将不会显示。

现在,如果你想拥有自定义的 WebGrid 表头,为了实现这一点,我们必须添加以下代码

  <div style="display:@Model.Status">
        @{
            WebGrid objWebGrid = new WebGrid(Model.MeetingsObj,
            rowsPerPage:5,canPage:true);//allowing rowsperpage,paging allow or not
        }
        @objWebGrid.GetHtml(

     tableStyle:"Grid-table",
       headerStyle:"Grid-Header",
       alternatingRowStyle:"Grid-alt",
       selectedRowStyle:"Grid-selected",
       rowStyle: "Grid-rowstyle",
       footerStyle: "Grid-Footer",
       mode: WebGridPagerModes.All, //Specifies flags that describe the methods 
       // that are provided for moving between the pages of a WebGrid instance. 
       // source msdn.microsoft.com
    columns:
       objWebGrid.Columns
       (
           objWebGrid.Column(columnName: "MeetingID", header:"Meeting ID"),
           objWebGrid.Column(columnName: "MeetingName", header: "Name of Meeting"),
           objWebGrid.Column(columnName: "Format", header: "Name of Fomat"),
           objWebGrid.Column(columnName: "Location", header: "Location at")
           )
       )
   </div>

通常在项目中,我们需要将整个网格导出到 Excel,所以现在我们将它导出到 Excel。

为了实现这一点,我们只需创建一个表单并插入一个提交按钮,如下所示。

我创建了一个方法类型为 Post 的表单,它会命中一个名为 ExportHeade 的操作。

<form id="exportWebGrid" action="Meeting/ExportHeade" method="post">

并添加一个提交按钮

  <input id="Submit1" type="submit" value="Export to Excel" />
    </form>

现在我们将编写一个 ActionResult 方法,如下所示,它将把网格导出到 Excel。

DataAccessLayer objDAL = new DataAccessLayer();
            MeetingVM objMeetingVM = new MeetingVM();
            objMeetingVM.MeetingsObj = new List<Meeting>();
            objMeetingVM.MeetingsObj = objDAL.MeetingMaster.ToList<Meeting>();
            WebGrid grid = new WebGrid
            (source: objMeetingVM.MeetingsObj, canPage: false, canSort: false);
            string gridData = grid.GetHtml(
                columns: grid.Columns(
                        grid.Column("MeetingID", "Meeting ID"),
                        grid.Column("MeetingName", "Name of Meeting"),
                        grid.Column("Format", "Name of Fomat"),
                        grid.Column("Location", "Location at")
                        )
                   ).ToString();
            Response.ClearContent();
            Response.AddHeader("content-disposition", 
            "attachment; filename=MeetingDetails.xls");
            Response.ContentType = "application/excel";
            Response.Write(gridData);
            Response.End();
            return View(objMeetingVM);

现在,当我不想要任何表头格式时,我可以简单地通过将 meeting 列表传递给 GridView 对象,然后导出它,如下所示。

        public ActionResult ExportHeade()
        {
            DataAccessLayer objDAL = new DataAccessLayer();
            MeetingVM objMeetingVM = new MeetingVM();
            objMeetingVM.MeetingsObj = new List<Meeting>();
            objMeetingVM.MeetingsObj = objDAL.MeetingMaster.ToList<Meeting>();
            GridView obj = new GridView();
            obj.DataSource = objMeetingVM.MeetingsObj;
            obj.DataBind();
            Response.AddHeader("content-disposition", 
            string.Format("attachment; filename={0}", "Meeting.xls"));
            Response.ContentType = "application/ms-excel";
           System.IO.StringWriter sw = new StringWriter();
            HtmlTextWriter htw = new HtmlTextWriter(sw);
            obj.HeaderRow.Style.Add("background-color", "#FFFFFF");
            for (int i = 0; i < obj.HeaderRow.Cells.Count; i++)
            {
                obj.HeaderRow.Cells[i].Style.Add("background-color", "#507CD1");
            }
            int j = 1;
            foreach (GridViewRow gvrow in obj.Rows)
            {
                gvrow.BackColor = Color.White;
                if (j <= obj.Rows.Count)
                {
                    if (j % 2 != 0)
                    {
                        for (int k = 0; k < gvrow.Cells.Count; k++)
                        {
                            gvrow.Cells[k].Style.Add("background-color", "#EFF3FB");
                        }
                    }
                }
                j++;
            }
            obj.RenderControl(htw);
            Response.Write(sw.ToString());
            Response.End();
           return View(objMeetingVM);
        }

显示用户点击生成到 Excel 后的图片

现在,如果用户想在 WebGrid 详细信息上执行删除等操作怎么办?为此,我们可以使用以下代码来实现

<form id="exportWebGrid" action="Meeting/ExportHeade" method="post">
        <div name="webView" style="display:@Model.Status">
            @{
                WebGrid objWebGrid = new WebGrid(Model.MeetingsObj, rowsPerPage: 5, canPage: true);
            }
            @objWebGrid.GetHtml(
       tableStyle: "Grid-table",
       headerStyle: "Grid-Header",
       alternatingRowStyle: "Grid-alt",
       selectedRowStyle: "Grid-selected",
       rowStyle: "Grid-rowstyle",
       footerStyle: "Grid-Footer",
       mode: WebGridPagerModes.All, //Specifies flags that describe the methods that are provided for moving between the pages of a WebGrid instance. source msdn.microsoft.com
    columns:
       objWebGrid.Columns
       (
           objWebGrid.Column(columnName: "MeetingID", header: "Meeting ID"),
           objWebGrid.Column(columnName: "MeetingName", header: "Name of Meeting"),
           objWebGrid.Column(columnName: "Format", header: "Name of Fomat"),
           objWebGrid.Column(columnName: "Location", header: "Location at"),
           objWebGrid.Column(format:@<text><a href="" 
           onclick="DeleteME('@item.MeetingID')">Delete</a></text>)
           )
    )  
        </div>
 <input id="Submit1" type="submit" value="Export to Excel" />
    </form>

在 Header 部分

<script>
         function DeleteME(id)
            {
                debugger;
                $.ajax({
                    type: 'POST',
                    url: 'https://:18175/meeting/DeleteMeeting',
                    data:{
                        MeetingId:id
                    }
            }); //e
        }
</script>

我们将创建一个 Action Result 来处理 post 请求,从数据库中删除数据并返回新记录。

[HttpPost]
        public ActionResult DeleteMeeting(Meeting objMeeting)
        {
            MeetingVM obj = new MeetingVM();
            DataAccessLayer objDAL = new DataAccessLayer();
          objDAL.MeetingMaster.RemoveRange
          (objDAL.MeetingMaster.Where(c => c.MeetingId == objMeeting.MeetingId));
            objDAL.SaveChanges();
            obj.MeetingsObj = objDAL.MeetingMaster.ToList<Meeting>();
            return View(obj);
        }

这里,我们创建了 Meeting 对象,meeting id 将从 ajax 调用中传递,我们可以根据需要传递更多属性,这个 meeting id 将与 Meetings 列表进行比较,并从中移除,同时也会对 db 进行更改。如下图所示

一旦用户点击特定行的删除按钮,DeleteMeeting 操作方法将被调用,如下所示,请注意,我点击了 Meeting ID 为 4 的记录。

继续,这个 meeting id 将被从 DB 中删除并进行更改,之后,我们获取更新后的 Meeting 记录列表并将它们传递给 View。

正如你所见,第 4 个 Meeting ID 已被删除。

如果你想从头开始学习 MVC,可以观看下面的视频

© . All rights reserved.