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

使用 DevExpress ASP.NET MVC 扩展实现主从明细

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.44/5 (8投票s)

2011年1月30日

CPOL

6分钟阅读

viewsIcon

66159

强制使用 DevExpress ASP.NET MVC V2010 vol 2 扩展实现主从明细

引言

主从明细网格是用户界面中根深蒂固的明星功能。不幸的是,如果您使用 ASP.NET MVC 2 和 Developer Express ASP.NET MVC 扩展的当前版本 V2010 vol 2 来开发 Web 应用程序(参见参考文献 1 和 2),您将无能为力——至少在您找到这篇短文之前是这样。

我们相信有一天 Developer Express 会提供一个绝佳的解决方案来满足这个需求。供应商意识到了这个需求,他们承诺未来会提供这个功能:“不幸的是,MVCxGridView 不支持这样的功能。我决定将这个问题转换为一篇建议文章并转发给我们的开发人员,以便他们进行审查。我们将在 2010 年 5 月 28 日(参见参考文献 3)得到 Vest 的答复,届时我们将告知您结果。”

目前,您需要阅读本文的其余部分,并在代码中做一些额外的工作,才能在 MVC Web 项目的 DevExpress GridView 中实现主从明细。

作者注(2011 年 5 月 31 日):事情就这样发生了。Developer Express 宣布,即将发布的 Developer Express ASP.NET MVC 扩展 V2011 vol 1 的一部分将包含 ASP.NET MVC GridView - 主从明细网格布局(参见参考文献 5)。该版本肯定会使读者免于使用本文描述的技巧。

背景

我们假设您熟悉 ASP.NET MVC 2 开发,并且您已经

  1. 安装了 Microsoft Visual Studio 2010(我们不知道任何与 VS 2008 不兼容的原因。我们没有机会测试。)
  2. 拥有 DevExpress 的试用版或包含 ASP.NET MVC 扩展的任何软件包的许可版本。我们使用 Developer Express V2010 vol 2 进行过测试。

先解决问题,再讨论细节

如果您和我一样,亲爱的读者,您会欣赏简洁的表达。因此,无需过多铺垫,我将引导您完成需要执行的步骤。稍后将有足够的空间讨论背景信息。

假设您已经有一个带有某些模型和控制器的 ASP.NET MVC 2 解决方案。如您所知,要使用 DevExpress GridView,您需要将所有核心内容放入一个部分页面中,然后将其渲染到列表操作页面(为了简单起见,我们称之为 Index)。

<%@ Page Title="Cool Master-Detail GridView" Language="C#" 
MasterPageFile="~/Views/Shared/Site.Master" 
Inherits="System.Web.Mvc.ViewPage<IEnumerable<MyParentTable>>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
      Cool Master-Detail GridView
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
     <% Html.RenderPartial("IndexPartial"); %>
</asp:Content>

您可能已经注意到,我们将部分视图命名为 IndexPartial,现在我们准备创建它。您可能已经创建了该视图页面,也可能准备开始编写。也许您想使用脚手架来生成视图。好吧,我听到了;脚手架非常适合普通列表,但对于 DevExpress GridView 却不可用,对吗?请听我说,请前往 CodePlex(参见参考文献 4),下载您尊敬的作者为您发布的 MVC Templates for DevExpress(注意:我们不将模板作为本文的下载内容,而是引用 CodePlex,因为模板不是本文的主要主题,而且 CodePlex 拥有出色的版本控制功能,因此您可以始终获取最新的模板。)

现在您已经有了提供主网格的 IndexPartial.ascx 页面。我假设您的控制器中已经有了 IndexIndexPartial 操作。您的代码可能与我的类似

// GET: /Index/
public ActionResult Index()
{
    IQueryable main = db.GetMasterData();
    return View(main);
}
 
// to support GridView sorting and other peculiarities
public ActionResult IndexPartial()
{
    IQueryable main = db.GetMasterData();
    return View(main);
}

注意:我们确实注意到两个操作中的代码完全相同。本文完成后,我们将处理 DRY(Don't Repeat Yourself)原则。

现在,让我们开始准备详细网格,首先是控制器操作。假设主网格和详细网格将使用 MasterId(主网格的主键)连接。

[ChildActionOnly]
public ActionResult DetailIndexPartial(int MasterId)
{
    var details = db.GetDetailData(MasterId);
    return View();
}

正如我们敏锐的读者肯定注意到的,我们将详细信息页面存储在其自己的部分视图中。我们可以使用与创建主网格部分视图相同的脚手架模板来创建 DetailIndexPartial 视图。

现在我们准备施展魔法了!

施展魔法 - 将详细信息渲染添加到 IndexPartial.ascx 视图中

1.  <%@ Control Language="C#" 
	Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<MyParentTable>>" %>
2.   
3.  <% 
4.      Html.DevExpress().GridView(
5.          settings =>
6.          {
7.              settings.Name = "gvMainTable";
8.              settings.CallbackRouteValues = 
		new { Controller = "Home", Action = "IndexPartial" };
9.              settings.Width = Unit.Percentage(100);
10.            settings.Columns.Add("MasterId").Caption = 
		"Primary key -- not for user eyes!";
11.            settings.Columns.Add("Name");
12.            settings.Columns.Add("Country");
13.            settings.Columns.Add("Notes");
14.            settings.Columns.Add("Active");
15.            settings.Columns.Add("Edited");
16.            settings.Columns.Add("EditedBy");
17.            settings.Settings.ShowPreview = true;
18.            settings.SetPreviewRowTemplateContent(c =>
19.                 Html.RenderAction("DetailIndexPartial", 
		new { MasterId = DataBinder.Eval(c.DataItem, "MasterId") }));
20.            var commandColumn = settings.Columns.Add("", "");
21.            commandColumn.SetDataItemTemplateContent(c =>
22.            {%>
23.                <%= Html.ActionLink("Edit", "IndexEdit", new 
			{ Id = DataBinder.Eval(c.DataItem, "Id") })%> 
24.                <%= Html.ActionLink("Delete", "IndexDelete", new 
			{ Id = DataBinder.Eval(c.DataItem, "Id") },
25.                        new { onclick = "return confirm
			('Do you really want to delete this record?')" })%>
26.            <%});
27.            commandColumn.Settings.AllowDragDrop = DefaultBoolean.False;
28.            commandColumn.Settings.AllowSort = DefaultBoolean.False;
29.            commandColumn.Width = 70;
30.        })
31.        .Bind(Model)
32.        .Render();
33.%>
34. 
35.    <p>
36.        <%: Html.ActionLink("Create New", "Create") %>
37.    </p>

我们添加了 3 行:17-19,其余部分来自脚手架。我们还为第 1 列(第 10 行)添加了标题,提醒您删除此列(删除第 10 行)可能是一个好主意。

运行项目,欣赏主从明细页面。

我喜欢!我能多要一些吗?

多于一个级别的表嵌套通常不被认为是最佳用户界面设计实践。然而,我们经常被要求这样做,有时这样做甚至是有意义的。那么,我们能否重复我们刚才所做的?是的,我们可以(无双关语)。我们将向 DetailIndexPartial 操作添加一行(注意第 5 行)。

1.  [ChildActionOnly]
2.  public ActionResult DetailIndexPartial(int MasterId)
3.  {
4.      var details = db.GetDetailData(MasterId);
5.      ViewData["MasterId"] = MasterId;
6.      return View();
7.  }

热切的读者已经猜到了,我们需要在控制器中创建一个 DetailAnotherIndexPartial 操作,使用第三个网格来脚手架部分视图,并将其渲染插入到 IndexPartial 视图中(与上面示例中的第 17-19 行相同,第 19 行将引用 DetailIndexPartial 并向其传递 DetailId)。我们需要修改另外两行。我们修改第 7 行

settings.Name = "gvDetailTable" + ViewData["MasterId"];

我们也修改第 36 行

<%: Html.ActionLink("Create New", "CreateDetail", 
new { MasterId = ViewData["MasterId"] })%>

再次运行项目,欣赏所有 3 个嵌套级别。

我们做了什么?

GridView 的预览行用于在主表中插入嵌套表。我们在第 17 行启用预览。我们在第 18 行模板化预览的内容,最后在第 19 行使用 RenderAction HTML 辅助方法插入详细表。

要启用多级嵌套,我们需要将主键添加到第一个详细信息的模型数据中。我们在 DetailAnotherIndexPartial 操作的第 5 行完成了这一点。我们使用此值来确保每个嵌套表都有一个唯一的名称。这在视图的第 7 行完成。

在主从明细表的每个嵌套级别都拥有“创建新项”功能是很少见的。我们之所以拥有它,是因为 ListPartialWithDexGridView 模板插入了它。删除操作链接(第 35-37 行)是一个简单的修复。或者,为了确保它正常工作,我们在修改第 36 行时向您展示了如何使用带有主表键的 ViewData。当然,您需要通过 CreateDetail 操作和视图来支持该功能。

我们没做什么?

主从明细网格具有那些精巧的 + 和 - 图标,您可以单击它们来显示或隐藏详细信息。有很多方法可以实现此行为。我们将尝试一次,以防时间允许。如果您在我之前完成了表的详细信息折叠,您介意给我发封电子邮件吗?

参考文献

  1. ASP.NET MVC 概述 – GridView 在
    http://documentation.devexpress.com/#AspNet/CustomDocument8998
  2. 如何在 MVC Web 应用程序中使用 DevExpress 扩展入门,位于 http://www.devexpress.com/Support/Center/p/K18376.aspx
  3. MVC 中的主从明细视图 – 问题报告,位于
    http://www.devexpress.com/Support/Center/p/Q260747.aspx
  4. 适用于 DevExpress 的 MVC 模板,位于
    http://devxmvctempates.codeplex.com/
  5. ASP.NET MVC GridView - 主从明细网格布局公告
    Mehul Hary 的博客

历史

  • 2011 年 1 月 30 日:初始帖子
  • 2011 年 5 月 31 日:文章更新,请参阅上面的作者注
© . All rights reserved.