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

ASP.NET 中的嵌套 GridView 控件:最佳实践

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.90/5 (8投票s)

2011年7月13日

CPOL

2分钟阅读

viewsIcon

92669

ASP.NET GridView 控件在以数据为中心的 Web 应用程序中托管另一个 GridView

通用解决方案

在 ASP.NET 中嵌套 GridView 控件几乎在 Microsoft 的“规范”演练 [1] 中有所描述。通常,它需要创建两个 GridView 控件:第一个作为容器或主 GridView1,具有其自己的 DataSource1 (SqlDataSourceAccessDataSource 等),第二个“嵌套”GridView2,其底层 DataSource2 位于主 GridView1TemplateField 中。代码片段 [1] 在 GridView1 RowDataBound 事件过程 (GridView1_RowDataBound) 内部,用于将“外键”值从 GridView1 传递到 DataSource2。在 [1] 中提供的特定示例中,存储在 GridView1 第一单元格中的“外键” (e.Row.Cells[0].Text) 被传递给 SqlDataSource2 的仅一个 SelectParameter (SelectParameters[0]) 的 DefaultValue 属性

清单 1. MSDN 上带有硬编码 Cells 索引的原始解决方案

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e){
  if (e.Row.RowType == DataControlRowType.DataRow)
  {
    SqlDataSource s = (SqlDataSource)e.Row.FindControl("SqlDataSource2");
    s.SelectParameters[0].DefaultValue = e.Row.Cells[0].Text;
  }
}
这应该适用于所有实际版本的 ASP.NET (2.0/3.5/4.0)。但是,此解决方案的潜在缺点在于外键值(例如,ID)可能会从 GridView1 控件的可见字段集中省略。此外,即使此外键字段存在于 GridView1 中,也可能存在硬编码单元格索引 0 的不便;通常,它可能不是字段集中的第一个,并且它的索引也可能在数据表编辑操作期间或由于动态重新排列表列顺序而动态更改。

更好的解决方案

以下清单 2 中显示的更好解决方案通过在 GridView1 控件中使用命名的 DataKeys 作为第二个 DataSource 的“外键”,有效地解决了上述所有潜在问题。在此特定示例中,DataKeyComposer”被添加到 GridView1 控件的 DataKeys 中(需要 DataKeyNames="Composer" 行),以便传递到第二个 DataSource (名为 “dsMusic”) 的相应 select 参数 s.SelectParameters[0].DefaultValue

清单 2. 使用 DataKeys 的改进版本

protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e) {
  if (e.Row.RowType == DataControlRowType.DataRow)
   {
     // find DataSource used for nested GridView (could be SqlDataSource)
     AccessDataSource s = (AccessDataSource)e.Row.FindControl("dsMusic");
     // assign parameter’s default value from the DataKeys in GridView1
     s.SelectParameters[0].DefaultValue = Convert.ToString(((GridView)sender).DataKeys[e.Row.RowIndex].Values["Composer"]);
   }
}
注意:清单 2 演示了 ASP.NET AccessDataSource 的使用,但概念/用法与 SqlDataSource 几乎相同。

示例演示

在线音乐库,带有附加的 YouTube 播放器 [2-4],使用上述嵌套 GridView 技术实现:单击下面的图片以查看工作演示: Music Library implemented as nested GridView controls

性能提升

通过为嵌套 DataSource 启用缓存并使用 FilterParameters 而不是 SelectParameters,可以实现显著的性能改进。为此
  1. 设置嵌套的 DataSource 属性; FilterExpression="Composer ='{0}'" EnableCaching="True"
  2. 通过替换将 SelectParameters 分配给以下行的行来修改清单 2 中的事件过程
    // assign filter parameter default value from the datakey
    s.FilterParameters[0].DefaultValue = Convert.ToString(((GridView)sender).DataKeys[e.Row.RowIndex].Values["Composer"]);
...瞧(就是这样!)

参考文献

  1. 演练:创建嵌套的 GridView 控件[^]
  2. 作为嵌套 GridView 控件实现的音乐库 [^]
  3. ASP.NET 的 YouTube™ API[^]
  4. YouTube™ 嵌入式视频播放器:扩展 API (C#)[^]
© . All rights reserved.