GridView 行内主/详细记录显示






4.60/5 (42投票s)
2006 年 1 月 9 日
6分钟阅读

774246

11684
如何使用 GridView 控件在主记录旁边内联显示详细记录。
引言
此代码片段是“一锅端”系列文章的一部分。如果您时间紧迫,可以直接复制代码并插入您的应用程序,无需理解。当您有时间时(说得好像会那样一样),您可以回顾一下源代码。
背景
我曾接到一个项目,需要将一个单用户 Access 应用程序转换为一个基于 Web 的多用户 SQL Server 应用程序。该 Access 应用程序大约有 10 个表需要通过 Add/Edit/Delete 界面进行管理。这些表的维护将由一个人完成,因此并发问题不是问题。我决定,通过一些调整,GridView
可以完成所需的工作。开箱即用的 GridView
不支持行插入,也不会提供 DropDownList
来编辑真正代表另一表行 ID 的数据。还有另一篇 CodeProject 文章 GridViewRedux
,它会教您如何做到这一点。您必须先阅读那篇文章,否则本文将毫无意义。
本文将展示如何像 Access 一样,在选定的主记录正下方内联编码详细记录。在本例中,我使用了 Northwind 数据库中的表。
使用代码
下载项目,将其解压缩到硬盘上的某个位置,然后从现有文件夹创建新的 Web 项目。生成项目,并进行测试驱动,以便您可以看到它的作用。有几个关键文件
- GridViewHelper.js 负责所有 DHTML 的繁重工作。
- Master.aspx 包含主记录
GridView
。 - Details.aspx 包含详细记录。
请下载源文件,并跟随我的解释,了解需要插入的内容。
Master.aspx
将此代码插入文件中的 <head>
部分
<script src="GridViewHelper.js" type="text/javascript"></script>
<link href="GridViewHelper.css" rel="STYLESHEET" type="text/css" />
<link href="AppStyle.css" rel="STYLESHEET" type="text/css" />
将此代码插入 </form>
元素之后
<script type="text/javascript">
GridViewHelper.Init(document.all.GridView1, 0, 0);
var ToolTips = new Array("", "??", "??", "??");
GridViewHelper.AddToolTips(document.all.GridView1, ToolTips);
</script>
- 由于这是一个主页面而不是详细页面(代码会检测到它不是在
IFRAME
中运行),因此Init
函数会调整页面的宽度以达到所需宽度,从而防止列换行。如果您不需要此功能,请不要在主页面中调用Init
。其他参数是必需的,但会被忽略。 GridView
控件不支持列标题上的工具提示,因此GridViewHelper
有一个方法AddToolTips
,它接受一个指向网格的引用和一个工具提示数组,并将其应用于列标题。将 "??" 更改为您想要的任何内容。
Master.aspx.cs
这里的大部分代码只是样板代码,直接复制粘贴即可。有两行代码比较有趣
string RowID = Convert.ToString(
System.Web.UI.DataBinder.Eval(e.Row.DataItem, "CategoryID"));
string Url = "Details.aspx?ID=" + RowID;
调用 Details.aspx 时,您必须告知它是关于哪个类别的详细信息。这是实现方式。
Details.aspx
注意 <body>
已被修改。这是为了使详细信息“紧贴”主记录,并向右偏移 40 像素,以便详细信息表可以缩进显示。此外,滚动条已关闭。您可以安全地关闭滚动条,因为主页面已被加宽。同样,这是为了“紧贴”详细记录。
<body leftmargin="40" topmargin="0" scroll="no">
将此代码插入文件中的 <head>
部分
<script src="GridViewHelper.js" type="text/javascript"></script>
<link href="GridViewHelper.css" rel="STYLESHEET" type="text/css" />
<link href="AppStyle.css" rel="STYLESHEET" type="text/css" />
注意 <form>
已被修改。更多“紧贴”
<form id="form1" runat="server" style="overflow: hidden;">
注意 <div>
已被修改。更多“紧贴”
<div style="overflow: hidden;">
现在是魔术。将此代码插入 </form>
元素之后
<script type="text/javascript">
GridViewHelper.Init(document.all.GridView1,
ExtraWidth=100, ExtraHeight=0);
var ToolTips = new Array("", "Product name",
"Supplier", "Quantity per unit",
"Unit price", "Units on order",
"Reorder level", "Discontinued");
GridViewHelper.AddToolTips(document.all.GridView1, ToolTips);
</script>
这使得放置详细信息的 IFRAME
仅具有必要的大小。最终的“紧贴”。注意上面的 ExtraWidth=100, ExtraHeight=0
参数。当 <body>
中的 scroll
设置为 no
时,您无需做任何事情,因为这些参数值应该足够了。如果您将 scroll
设置为 yes
,则可能会出现滚动条,您需要为它们腾出空间。这时您需要通过尝试更改 ExtraWidth
/ExtraHeight
参数为较大的数字来让详细记录显示正确(尽量少滚动条)。您永远不需要垂直滚动条,因为代码会调整到正确的高度。如果您将 ExtraHeight=25
,您应该有足够的空间容纳水平滚动条,而无需垂直滚动条。
看看 DataSource
行
SelectCommand="SELECT '0' as [ProductID], '' as [ProductName],
'' as [CompanyName], '0' as SupplierID, '0' as [QuantityPerUnit],
'0.00' as [UnitPrice], '0' as [UnitsInStock], '0' as [UnitsOnOrder],
'0' as [ReorderLevel], '0' as [Discontinued]
UNION SELECT [ProductID], [ProductName], Suppliers.CompanyName,
Suppliers.SupplierID, [QuantityPerUnit],
convert(varchar(20), [UnitPrice], 0) as [UnitPrice],
[UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued]
FROM [Products]
left join Suppliers on Suppliers.Supplierid=Products.SupplierID
WHERE ([CategoryID] = @CategoryID)
ORDER BY [ProductName]
请注意,SELECT
语句正在等待一个 QueryString
参数来插入 WHERE
子句。如果您点击 DataSource
的智能标记,选择配置数据源,然后单击 Next 一次,您将看到一个WHERE 按钮。点击它可以看到此子句是如何创建的。另请注意,我已经将 UnitPrice
转换为字符串,以便它只显示两位小数。
看看 DataSource
行
InsertCommand="INSERT INTO [Products] ([ProductName],
[SupplierID], [CategoryID], [QuantityPerUnit], [UnitPrice],
[UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued])
VALUES (@ProductName, @SupplierID, @CategoryID,
@QuantityPerUnit, convert(money,@UnitPrice),
@UnitsInStock, @UnitsOnOrder, @ReorderLevel, @Discontinued)
我必须将字段转换回 money 类型,这样插入才不会因为“从 varchar 转换为 money 的错误”而失败。
Details.aspx.cs
这里的大部分代码只是样板代码,直接复制粘贴即可。这里只有一个技巧,与插入新记录有关
p = new System.Data.SqlClient.SqlParameter(
"@CategoryID", Request.QueryString["ID"]);
c.Parameters.Add(p);
插入需要一个 CategoryID
,您可以通过 QueryString
获取它。
关注点
此技术的一个有趣的副作用是,详细记录可以拥有自己的详细记录,无限循环。当您第一次展开一个详细信息块时,会向服务器发出一个请求来填充它。如果您折叠详细信息块,该块只会隐藏起来,因此下次您请求展开时,不会有服务器命中,只需再次显示该块即可。
注意:在本篇文章的创建过程中,没有AJAX 被伤害或杀死。事实上,最新的技术(AJAX)也不是必需的。我对 AJAX 没有意见(事实上我的一些朋友也在使用 AJAX),但它有其适用时间和地点(可能在我的下一个项目中 ;-)。
一锅端 / Redux 系列
我最近在 CodeProject 开始了两个系列的文章。一锅端(Smash and Grab)旨在提供关于特定代码技术的简短文章。Redux 旨在提供更长的文章,试图将复杂的主题(如 GridView
)分解成其基本组成部分,并表明一旦您掌握了所有信息,它实际上并没有那么难。要查找“一锅端”文章,请搜索关键字 SmashGrab。要查找 Redux 文章,请搜索关键字 Redux。我欢迎为这两个系列贡献内容,但在提交文章时请遵循指南。
结论
很简单,是吧!(我是加拿大人)。如果您有时间,请看看源代码,里面有一些很酷的 DHTML 技术。