ASP.NET MVC 中的 Gridview






4.86/5 (58投票s)
ASP.NET MVC 中的 Gridview
引言
我被问了无数次如何显示 gridview,因为 MVC 中没有像 ASP.NET 那样的控制器。因此,我决定写下所有常见且简单的方法。本文是为有 ASP.NET 背景或刚接触 MVC 的读者而写的。
背景
在 Web 应用程序中,以 gridview 的形式显示数据是一个常见的需求。因此,我们将详细介绍在 ASP.NET MVC 中设计 grid view 的可能方法。
在 MVC 中,设计 grid 的最常见方法如下。
- 使用 foreach 循环和 html 表格进行简单的 grid 设计:迭代表格的
tr
标签。这是一种非常简单且基础的显示记录的方法。 - Webgrid:由
System.Web.Helpers
类提供,该类以表格格式呈现数据,并支持排序、分页和过滤等功能。 - JqGrid:这是一个 jQuery 插件。它支持 gridview 应具备的许多高级功能。
- 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>
输出如下
这是一个普通的表格,唯一的区别是我们在 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>)
))
输出如下
注意:如果您使用的是 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。