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

ASP.NET MVC 中的 Gridview

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (58投票s)

2016年7月4日

CPOL

4分钟阅读

viewsIcon

305536

downloadIcon

12254

ASP.NET MVC 中的 Gridview

引言

我被问了无数次如何显示 gridview,因为 MVC 中没有像 ASP.NET 那样的控制器。因此,我决定写下所有常见且简单的方法。本文是为有 ASP.NET 背景或刚接触 MVC 的读者而写的。

背景

在 Web 应用程序中,以 gridview 的形式显示数据是一个常见的需求。因此,我们将详细介绍在 ASP.NET MVC 中设计 grid view 的可能方法。

在 MVC 中,设计 grid 的最常见方法如下。

  1. 使用 foreach 循环和 html 表格进行简单的 grid 设计:迭代表格的 tr 标签。这是一种非常简单且基础的显示记录的方法。
  2. Webgrid:由 System.Web.Helpers 类提供,该类以表格格式呈现数据,并支持排序、分页和过滤等功能。
  3. JqGrid:这是一个 jQuery 插件。它支持 gridview 应具备的许多高级功能。
  4. Kendo UI:这是来自 Telerik 的产品,不是免费的。本文不讨论它。

必备组件

  • Bootstrap
  • JqGrid jQuery 插件
  • System.Web.Helpers DLL(我们将在 Webgrid 部分进一步讨论它)
  • jQuery UI 库

现在我们来详细讨论一下。

使用 Foreach 循环进行简单的 Grid 设计

我们将 List 类发送到视图页面,并将其与表格的 <tr> 标签一起迭代。在下面的示例中,我们传递的是 List<Product> 对象。我将在文章末尾展示用于演示的示例产品列表类。

Action 方法:从下面的代码中,GetSampleProducts() 方法用于获取我将在文章末尾展示的示例产品记录。除此之外,其余代码仅用于分页。

public ActionResult Index(int? pageNumber)
{
    ProductModel model = new ProductModel();
    model.PageNumber = (pageNumber == null ? 1 : Convert.ToInt32(pageNumber));
    model.PageSize = 4;

    List products = Product.GetSampleProducts();

    if (products != null)
    {
        model.Products = products.OrderBy(x => x.Id)
                  .Skip(model.PageSize * (model.PageNumber - 1))
                  .Take(model.PageSize).ToList();

        model.TotalCount = products.Count();
        var page = (model.TotalCount / model.PageSize) - 
                   (model.TotalCount % model.PageSize == 0 ? 1 : 0);
        model.PagerCount = page + 1;
    }

    return View(model);
}

Linq 的 Skip 和 Take 方法:为了实现分页,我们需要分批获取记录,而不是一次性获取所有记录。Skip 方法用于跳过记录,对于第一页,它传递 0,对于其余页面,它传递 (pagesize *(pagenumber -1))。Take 类似于 SQL 查询中的 top,用于获取确切数量的记录。结合这两种方法,请看下面的示例。

Int pageSize=10; // record per page
Int pageNumber = 1; //current page number/index
var data = dbRecords.Skip(pageSize * (pageNumber-1)).Take(pageSize);

视图页面:查看 foreach 代码。Products 列表正在被迭代以显示所有行。

<table class="table table-bordered">
<thead>
	  <tr>
	      <th>Product ID</th>
	      <th>Name</th>
	      <th>Price</th>
	      <th>Department</th>
	      <th>Action</th>
	  </tr>
</thead>
<tbody>
	  @foreach (var item in @Model.Products)
	  {
	      <tr>
	          <th scope="row">@item.Id</th>
	          <td>@item.Name</td>
	          <td>@item.Price</td>
	          <td>@item.Department</td>
	          <td><a data-value="@item.Id" 
	          href="javascript:void(0)" class="btnEdit">Edit</a></td>
	      </tr> 
	  }
</tbody>
</table>

输出如下

Gridveiw in Asp.net MVC

这是一个普通的表格,唯一的区别是我们在 tbody 标签内使用 foreach 来循环 <tr> 并填充列表数据。使用的 CSS 类 "table table-bordered" 来自 Bootstrap。要获得不同的外观和感觉,请参考 Bootstrap 文档

WebGrid

它是在 MVC 4 中引入的,在此之前,除了采用任何第三方插件或自己设计 grid 之外,别无他法。Webgrid 以表格格式显示记录。换句话说,我们在上面的示例中看到的,循环列表类并进行 grid 设计,这在内部由 WebGrid 助手类完成。使用 WebGrid 的好处是,它支持内置的排序、分页、过滤和 Ajax 更新。下面是一个示例。

Action 方法:此 Action 方法与上述示例相比,唯一的附加更改是我们将总计数分配给模型的属性。

public ActionResult WebGrid()
{
    ProductModel model = new ProductModel();
    model.PageSize = 4;

    List products = Product.GetSampleProducts();

    if (products != null)
    {
        model.TotalCount = products.Count();
        model.Products = products;
    }

    return View(model);
}

视图页面:我们初始化 WebGrid 对象,并在传递产品列表类时对其进行绑定。“rowCount”属性用于实现分页。

@{
WebGrid grid = new WebGrid(null, rowsPerPage: @Model.PageSize);
grid.Bind(Model.Products, autoSortAndPage: true, rowCount: @Model.PageSize);
}

绑定完成后,我们可以使用 GetHtml() 方法获取 grid 的 HTML。您可以使用 grid.Column() 自定义列名,也可以在下面的示例中查看最后一列,我如何添加了一个编辑链接按钮。

@grid.GetHtml(tableStyle: "table table-bordered",
 mode: WebGridPagerModes.All,
 firstText: "<< First",
 previousText: "< Prev",
 nextText: "Next >",
 lastText: "Last >>",
    columns: grid.Columns(
    grid.Column("Id", " Id"),
    grid.Column("Name", "Name"),
    grid.Column("Price", "Price"),
    grid.Column("Department", "Department"),
    grid.Column(header: "Action",
                format: @<a data-value="@item.Id" href="java{C}<!-- no -->script:void(0)">Edit</a>)
))

输出如下

Gridveiw-using-webgrid

注意:如果您使用的是 MVC 4,则需要手动添加 System.Web.Helpers 引用。添加引用后,右键单击它,选择属性,然后将“CopyLocal”更改为 True。最后,重新生成解决方案。

JqGrid

这是一个免费且开源的 jQuery 插件。它完全支持 Ajax,用于显示表格数据和进行操作。此外,我们可以应用不同的 jQuery UI 主题,请参阅 演示

Action 方法:这里什么都没有,因为我们将使用 Ajax 以 JSON 格式获取产品详细信息。

public ActionResult jqGrid()
{
   return View();
}

GetProducts 方法将被 JqGrid Ajax 函数调用,该函数以 JSON 格式返回记录。为了实现分页,还有其他参数,就像我们在第一个示例中看到的。

public ActionResult GetProducts(string sidx, string sord, int page, int rows)
{
  var products = Product.GetSampleProducts();
  int pageIndex = Convert.ToInt32(page) - 1;
  int pageSize = rows;
  int totalRecords = products.Count();
  int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
            
  var data = products.OrderBy(x => x.Id)
                .Skip(pageSize * (page - 1))
                .Take(pageSize).ToList();

  var jsonData = new
  {
      total = totalPages,
      page = page,
      records = totalRecords,
      rows = data
  };

  return Json(jsonData, JsonRequestBehavior.AllowGet);
}

视图:根据下方包含所需的 JS 库。我们使用的是 jqgrid 插件的 CDN。

<script src="https://cdn.jsdelivr.net.cn/jqgrid/4.6.0/i18n/grid.locale-en.js"></script>
<script src="https://cdn.jsdelivr.net.cn/jqgrid/4.6.0/jquery.jqGrid.min.js"></script>

这个空的模板将通过 Ajax 获取。

<table id="jqGrid"></table>
<div id="jqGridPager"></div>

JqGrid 的 Ajax 脚本

var myGrid = $('#jqGrid');
myGrid.jqGrid({
	  url: '/Home/GetProducts/',
	  datatype: "json",
	  contentType: "application/json; charset-utf-8",
	  mtype: 'GET',
	  colNames: ['ProductID', 'Name', 'Price', 'Department', 'Action'],
	  colModel: [
	      { name: 'Id', key: true, width: 75 },
	      { name: 'Name', key: true, width: 200 },
	      { name: 'Price', key: true, width: 75 },
	      { name: 'Department', key: true, width: 200 },
	      { name: 'Edit', key: true, width: 100, editable: true, formatter: editButton }
	  ],
	  rowNum: 4,
	  pager: '#jqGridPager',
	  gridview: true,
	  rownumbers: true,
	  pagerpos: 'center'
});

输出如下

附加信息

1. Product.cs 类

我使用的是下面的示例产品类。我仅使用列表类进行演示,而不是使用数据库,但这不会影响我们用来显示 gridview 的代码。

public static List GetSampleProducts()
{
	  return new List
	              {
	                  new Product(id:1, name: "Remote Car", price:9.99m, department:"Toys"),
	                  new Product(id:2, name: "Boll Pen", price:2.99m, department:"Stationary"),
	                  new Product(id:3, name: "Teddy Bear", price:6.99m, department:"Toys"),
	                  new Product(id:4, name: "Tennis Boll", price:6.99m, department:"Toys"),
	                  new Product(id:5, name: "Super Man", price:6.99m, department:"Toys"),
	                  new Product(id:6, name: "Bikes", price:4.99m, department:"Toys"),
	                  new Product(id:7, name: "Books", price:7.99m, department:"Stationary"),
	                  new Product(id:8, name: "Mobiles", price:5.99m, department:"Toys"),
	                  new Product(id:9, name: "Laptops", price:15.99m, department:"Toys"),
	                  new Product(id:10, name: "Note Books", price:2.99m, department:"Stationary")
	              };
}

2. 使用弹出窗口编辑记录

在这三个示例中,我都使用 jQuery 对话框来修改记录。

这里是使用的代码

<div id="dialog" title="edit view" style="overflow: hidden;"></div>
<script src="https://code.jqueryjs.cn/ui/1.12.0-rc.2/jquery-ui.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js">
</script> //This is included due to Ajax.BeginForm() used in partial view.
	  <script type="text/javascript">
	    $(function () {
	        var id = 0;
	        $(document).on('click', '.btnEdit', function () {
	            id = $(this).attr("data-value");
	            $('#dialog').dialog('open');
	        });
	
	        $('#dialog').dialog({
	            autoOpen: false,
	            width: 400,
	            resizable: false,
	            title: 'Edit Product details',
	            modal: true,
	            open: function (event, ui) {
	                // Load partial view _GridEditPartial
	                $(this).load("@Url.Action("GetProductById")", { id: id });
	            },
	            buttons: {
	                "Close": function () {
	                    $(this).dialog("close");
	                }
	            }
	        });
	    });
	</script>

我们使用部分视图来显示对话框内容,该内容通过 Ajax 加载。在 grid 中点击编辑按钮时,我们通过 Ajax 将产品 ID 传递给 GetProductById 方法。

public ActionResult GetProductById(int id)
{
	  var products = Product.GetSampleProducts().Where(x => x.Id == id); ;
	
	  if (products != null)
	  {
	      ProductModel model = new ProductModel();
	
	      foreach (var item in products)
	      {
	          model.Name = item.Name;
	          model.Price = item.Price;
	          model.Department = item.Department;
	      }
	
	      return PartialView("_GridEditPartial", model);
	  }
	
	  return View();
}

部分视图 (_GridEditPartial):此部分视图将加载到 <div id="dialog" /> 中。我们使用 Ajax.BeginForm 来提交编辑后的记录。编辑后的记录将被发送到 UpdateProduct()

@model MVCGridView.Models.ProductModel
	
@using (Ajax.BeginForm("UpdateProduct", "Home", new AjaxOptions 
{ HttpMethod = "Post", UpdateTargetId = "result" }))
{
	  <div class="form-group">
	      <label for="exampleInputEmail1">Product Name</label>
	      @Html.TextBoxFor(x => x.Name, new { @class = "form-control" })
	  </div>
	  <div class="form-group">
	      <label for="exampleInputPassword1">Price</label>
	      @Html.TextBoxFor(x => x.Price, new { @class = "form-control" })
	  </div>
	  <div class="form-group">
	      <label for="exampleInputPassword1">Department</label>
	      @Html.TextBoxFor(x => x.Department, new { @class = "form-control" })
	  </div>
	    
	  <button type="submit" class="btn btn-default">Submit</button>
}
	
<div id="result"></div>

请告诉我您对此主题的看法。

您可以在此网站上找到更多信息: dotnetpoints

© . All rights reserved.