CodeProject 常见问题解答系列 1:ASP.NET GridView






4.94/5 (106投票s)
CodeProject 问答论坛中关于 ASP.NET GridView 的常见问题。
目录
- 引言
- 能否将 AutoGenerateColumns 设置为 true,并在“Columns”部分定义列?
- 如何使用显式定义的列绑定 GridView DataSource?
- 在 GridView 中格式化列值
- 如何访问 GridView 中 Template Fields 的值?
- 动态设置 GridView ItemTemplates 中控件的可见性
- 在 ASP.NET GridView 中显示 NULL 值时显示自定义消息/图像
- 绑定布尔值到 GridView 时,如何显示“是”或“否”而不是复选框?
- 如何使用 GridView HyperLinkField 传递多个值?
- 如何将 GridView HyperLinkField 中不属于 GridView DataSource 成员的外部值传递过去?
- 将 GridView 导出到 Excel
- 将 Excel 导入 GridView
- GridView 中的下拉列表
- 获取多个 DataKeys 的单个 DataKey 值
- 使用 EditItemTemplate 在 GridView 中显示 DropDownList
- 在 GridView 中显示图像
- 在 GridView 中显示累计总计
- 显示嵌套 GridView
- 历史
引言
在回答 问答论坛[^]中的问题时,我们注意到经常被问到的一些问题存在一定的模式。与其逐个临时回答每个问题,不如我们将一组常见问题汇总到一篇文章中。每次我们遇到类似模式的问题时,都会链接到这篇文章,而不是为每个问题提供答案。这将帮助我们更好地回答问题,用户也可以查看替代解决方案。
让我们从 ASP.NET 的 GridView
开始,它是 ASP.NET 中一个极其灵活的数据控件。我们观察到每天都有大量关于 ASP.NET GridView
的问题被提出。几乎每天都有关于将 GridView
导出到 Excel 的问题。关于 GridView
模板字段、隐藏单元格中的特定值、运行时更改单元格值等问题也非常普遍。
花一些时间在问答论坛上,可以发现许多其他类似的模式。
我们希望通过不断地向本文档添加更多常见问题来保持其更新。
能否将 AutoGenerateColumns 设置为 true,并在“Columns”部分定义列?
是的,可以。当启用 AutoGenerateColumns="true"
并定义自定义列时,这种情况并不常见。当 AutoGenerateColumns=true
时,GridView
会为每个字段生成列。当我们需要数据源中的特定字段,并需要定义不同类型的自定义列部分时,我们则会设置 AutoGenerateColumns=false
。
如果我们将 AutoGenerateColumns
设置为 true 并添加一个“Columns
”部分来定义列,会发生什么?GridView
会为每一个字段生成列,但在这些自动生成的列之前,它会添加你显式定义的列。
如何使用显式定义的列绑定 GridView DataSource?
GridView
允许通过多种类型的列显式绑定数据。最常见的列类型之一是 BoundField
。除了绑定字段,GridView
还支持不同类型的列,包括 ButtonField
、ImageField
、HyperLinkField
、TemplateField
等。让我们快速看一下如何使用 BoundField
来显式定义 GridView
列。
BoundField
有一个名为 DataField
的属性。DataField
需要与 GridView
DataSource
的任何数据对象相关联。
这种类型的列绑定为您提供了充分的自定义列和标题的机会。
在 GridView 中格式化列值
另一个常见问题是如何格式化单元格值?GridView
BoundField
列提供了一个名为“DataFormatString
”的属性,您可以使用它来格式化数据。DataFormatString
接受与 String.Format
类似的参数,其中包含一个占位符和一个格式指示符。
这是一个简单的日期格式化示例
这在我们需要格式化货币字段时也非常有用。您可以在 这里 找到所有格式字符串的列表。
如何访问 GridView 中 Template Field 的值?
GridView
TemplateField
允许我们使用自定义模板指定自定义控件、多个字段和 HTML。TemplateField
允许我们为 GridView
列定义完全自定义的模板。我们可以在模板控件中使用绑定表达式来绑定数据。ASP.NET 提供了多种方法来控制模板控件。
假设您的 GridView
设计如下:
现在,您想从代码隐藏访问此标签的值,您想更新文本,或者基于标签的值或其他值执行其他操作。在下面的代码片段中,如果姓名以“A”开头,则不会显示。
protected void myGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Customer cust = e.Row.DataItem as Customer;
if (!cust.ShowURL)
{
Label lableName = e.Row.FindControl("Label1") as Label;
if (lableName.Text.StartsWith("A"))
{
lableName.Visible = false;
}
}
}
}
因此,在任何情况下,如果您想访问模板字段内的控件,请首先检查该行是否为 DataRow
,然后使用 GridViewRow.FindControl
方法获取控件。一旦您获得相同类型的控件,您就可以执行所有其他操作。
动态设置 GridView ItemTemplates 中控件的可见性
如果您想根据某些条件值隐藏字段或控件,您可以从代码隐藏完成,也可以借助绑定表达式。
如果您采用代码隐藏方法,首先,您需要在 GridView
的 RowDataBound
事件中找到控件值。一旦您获得了控件,您就可以根据要应用的条件设置控件的可见性。
下面的示例演示了基于某些条件隐藏 LinkButton
protected void myGrid_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Customer cust = e.Row.DataItem as Customer;
if (!cust.ShowURL)
{
LinkButton lnkWebURL = e.Row.FindControl("lnk") as LinkButton;
if (lnkWebURL != null)
{
lnkWebURL.Visible = false;
}
}
}
}
当然,您可以通过仅使用绑定表达式以一种更智能的方式实现相同的功能。我们可以在 GridView
绑定表达式中使用条件表达式。因此,您在代码隐藏中编写的任何内容都可以被替换为
这将首先评估“ShowURL
”的值,然后设置 GridView
的 Visible
属性。
这个问题最近在问答论坛中被问到。我回答了这个问题,并在 使用绑定表达式动态设置 GridView ItemTemplates 中控件的可见性 上发布了一篇详细的博客文章。
在 ASP.NET GridView 中显示 NULL 值时显示自定义消息/图像
当我们用包含一些 NULL 值字段的数据源绑定 GridView
时,ASP.NET 会将其渲染为空白。但大多数时候,我们需要显示自定义消息或图像而不是 null 值。您可以使用 RowDataBound
方法来覆盖 null 值。与其这样做,不如利用 NullDisplayText
属性来替换 null 值。
这将把所有 null 值替换为纯文本“无数据”。
一旦我们有了 NullDisplayText=”无数据”
,该绑定字段中包含 NULL
值的每个字段都将被替换为“无数据”。
我们甚至可以像下面这样使用 HTML 格式来自定义文本
输出将如下所示
原始来源:在 ASP.NET GridView 中显示 NULL 值时显示自定义消息/图像。
绑定布尔值到 GridView 时,如何显示“是”或“否”而不是复选框?
如果您正在将一个包含 Boolean
类型字段的数据源绑定到 GridView
,那么 GridView
会将其渲染为一个复选框。但有时我们可能希望显示“是/否”或“1/0”而不是勾选/取消勾选的框。
您可以在 RowDataBind
事件中简单地更新单元格值,并根据需要更改默认值。
protected void GridView2_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Student s = (Student)e.Row.DataItem;
if (s.Status == true)
{
e.Row.Cells[2].Text = "1";
}
else
{
e.Row.Cells[2].Text = "0";
}
}
}
您可以在此处找到完整提示:绑定布尔值到 GridView 时,如何显示“是”或“否”而不是复选框?
如何使用 GridView HyperLinkField 传递多个值?
在 ASP.NET 中使用 GridView
时,大多数时候我们使用 HyperlinkField
列来导航从一个页面到另一个页面,并将一些值作为参数。在这里,我解释了如何使用 GridView
中的 HyperLinkField
传递多个参数。要实现此功能,您需要了解 HyperLinkField
的 DataNavigationUrlField
和 DataNavigateUrlFormatString
属性。假设您有一个 GridView
,如下所示,并且您已经从代码隐藏绑定了 DataSource
。
<asp:gridview id="GrdEmp">
<columns runat="server" autogeneratecolumns="False"
cellpadding="4">
<asp:boundfield datafield="ID" headertext="ID">
<asp:boundfield datafield="Name" headertext="Name">
<asp:boundfield datafield="ParentID" headertext="Base ID">
让我们首先考虑传递单个参数的情况。您需要做的第一件事是添加一个 GridView
HyperLinkField
列。之后,您需要设置 DataNavigationUrlField
和 DataNavigateUrlFormatString
属性。在 DataNavigationUrlField
中,您必须提及要作为查询字符串绑定的 DataField
的名称。在 DataNavigateUrlFormatString
中,您必须为导航提供格式化的 URL 字符串。这里的概念与 FormatString
相同 - 唯一的区别是数据来自 DataNavigationUrlField
。
<asp:hyperlinkfield text="Details" datanavigateurlfields="ID"
datanavigateurlformatstring="/Details.aspx?EmpId={0}">
在上面的示例中,我将 ID 作为 DataNavingationUrlField
传递。因此,当 GridView
绑定时,对于每一行,相应的 ID 将作为 URL 字符串与员工 ID 一起绑定。HTML 视图的代码就在下面
<a href="https://codeproject.org.cn/Default.aspx?EmpID=123">Details</a>
要添加多个参数,您需要在 DataNavigateURLField
中用逗号 (,) 分隔多个 DataField
,并且还需要提供具有适当参数数量的 DataNavigateURLFormatString
。
asp:hyperlinkfield datanavigateurlformatstring="/Details.aspx?EmpId={0}&ParentID={1}"
datanavigateurlfields="ID,ParentID" text="Details">
这是多参数 HyperLinkField
的 HTML 输出
<a href="https://codeproject.org.cn/Default.aspx?EmpID=123&ParentID=765">Details</a>
总结一下这篇文章,您可以使用逗号分隔的 DataNavigateURLField
来将多个 DataField
作为参数与 GridView
中的 HyperlinkField
一起传递。此外,您还需要使用带有 DataaNavigateURLFormatString
的正确格式化的 URL。
原始来源:如何使用 GridView HyperLinkField 传递多个值?
如何将 GridView HyperLinkField 中不属于 Gridview DataSource 成员的外部值传递过去?
DataNavigationUrlField
仅使用属于 GridView DataSource
的字段作为参数。现在的问题是,当您想将其他变量作为参数传递,而这些变量不属于 DataSource
时。如下图所示,我们传递了 EmpID
和 ParentId
作为参数,并且这两个字段是 GridView DataSource
的数据成员。
现在假设您想为该特定记录传递一个 ChildID
,以及 ParentID
和 EmpID
,并且您希望超链接 URL 类似于“Default.aspx?EmpID=1&ParentID=P1&ChildID=C1”,其中 ChildID
不属于数据源。
您可以通过为特定 GridView
编写代码隐藏来实现这一点。有两个事件可以覆盖该超链接字段的导航 URL。您可以使用 Gridview_RowDataBound
或 Gridview_PreRender
。
让我们从 Gridview_RowDataBound
开始。当数据行绑定到数据时,GridView
的 RowDataBound
事件会被引发。因此,对于每一行,都会引发 RowDataBound
事件以绑定来自数据源的实际数据。在 RowDataBound
事件中,您可以检查特定的单元格控件并附加 NavigateURL
。下面是代码片段
/// <summary>
/// Handles the RowDataBound event of the grdStudent control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see
/// cref="System.Web.UI.WebControls.GridViewRowEventArgs"/>
/// instance containing the event data.</param>
protected void grdStudent_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
HyperLink hyperlink = (HyperLink)e.Row.Cells[0].Controls[0];
hyperlink.NavigateUrl += "&ChildID=" + this.ExternalValue;
}
}
您可以在 Gridview_PreRender
事件中以类似的方式执行相同操作。根据 ASP.NET 页面的生命周期,控件的 Pre_Render
在保存视图状态和 Render
事件之前被引发。这是您在保存视图状态数据并呈现控件之前可以自定义控件的最后一个事件。下面是代码片段
/// <summary>
/// Handles the PreRender event of the grdStudent control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/>
/// instance containing the event data.</param>
protected void grdStudent_PreRender(object sender, EventArgs e)
{
foreach (GridViewRow row in grdStudent.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
HyperLink grdviewLink = (HyperLink)row.Cells[0].Controls[0];
grdviewLink.NavigateUrl += "&ChildID=" + this.externalValue;
}
}
}
如果您想了解它是如何工作的,只需在数据绑定事件期间设置一个断点,您就会发现该超链接字段的 NavigateURL
已经用您作为 DataNavigationUrlField
传递的值设置好了。并且在 RowDataBound
或 Pre_Render
内部,我们正在用外部参数附加相同的 NavigateURL
。
下面是 HyperLinkField
的 HTML 代码片段。
您可以使用 NavigateURL
属性来设置 Hyperlinkfield
的 URL,但是 NavigateURL
会为所有行设置相同的 URL。因此,如果您想要每一行都有不同的 URL,您需要使用 DataNavigationUrlField
,或者您需要在 RowDataBound
或 Pre_Render
期间覆盖 NavigateURL
。如果您同时设置了这两个属性(NavigateURL
和 DataNavigationUrlField
),则 DataNavigationUrlField
属性具有优先权。
将 GridView 导出到 Excel
如何将 GridView
导出到 Microsoft Excel 是论坛中最常见的问题之一。这个方法相当简单。GridView
可以逐行复制到一个 HTML 表中。这个表可以写入一个 HTML 流,在那里我们就有了 Excel。
让我们看一些代码。UI 非常简单,有一个包含一些数据的 GridView
和一个“导出到 Excel”按钮。UI 看起来会是这样的
UI 代码只有两行,为完整起见在此显示。
<asp:gridview runat="server" autogeneratecolumns="true"
height="66px" width="543px" style="z-index: 118" id="GridView1">
<asp:button onclick="Button1_Click" text="Export to Excel" runat="server" id="Button1">
主代码写在按钮的点击事件中。我们将使用 HttpContext
的 Response
对象。向 Response
对象添加一个 Excel 头部(带有相应的 MIME 类型)。
首先创建一个 StringWriter
对象。然后从此 StringWriter
创建一个 HtmlTextWriter
对象。然后创建一个 HTML Table
,并将 GridView
逐行复制到此表中。然后将此表渲染到 HtmlTextWriter
对象中。然后将 StringWriter
对象写入 Response
,浏览器就可以将响应解析为 Excel 文件(前提是它能识别 Excel MIME 类型)。
这是代码
protected void Button1_Click(object sender, EventArgs e)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition",
string.Format("attachment;filename={0}.xls", "Exported"));
HttpContext.Current.Response.Charset = "";
HttpContext.Current.Response.ContentType = "application/ms-excel";
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// Create a table to contain the grid
Table table = new Table();
foreach (GridViewRow row in GridView1.Rows)
{
table.Rows.Add(row);
}
// render the table into the htmlwriter
table.RenderControl(htw);
// render the htmlwriter into the response
HttpContext.Current.Response.Write(sw.ToString());
HttpContext.Current.Response.End();
}
}
}
http://mattberseth.com/blog/2007/04/export_gridview_to_excel_1.html[^] 是一个关于将 GridView
导出到 Excel 的好链接,这也是在准备本技巧时参考的。
GridView 导入 Excel 到 GridView
一个常见问题(尽管不如导出到 Excel 那么常见)是将 Excel 文件导入 GridView
。在这个例子中,我们将使用一个 FileUpload
控件来从驱动器中选择一个 Excel 文件。请注意,由于安全原因,FileUpload
不会将完整的文件路径返回到服务器。UI 及其代码如下所示
提供了一个“导入”按钮来执行实际的导入到 GridView
。使用绑定来允许 GridView
绑定到导入的数据。下面显示了导入按钮 Click
事件中的代码隐藏。
protected void Import_Click(object sender, EventArgs e)
{
DataSet ds = new DataSet();
String strConn = @"Provider = Microsoft.ACE.OLEDB.12.0;" + @"Data Source=C:\" +
MyFile.FileName + @";Extended Properties='Excel 12.0;HDR=Yes;'";
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", strConn);
da.Fill(ds);
GridView1.DataSource = ds.Tables[0].DefaultView;
GridView1.DataBind();
}
以上代码中的几行需要解释。在此示例中,Jet 引擎用于将 Excel 文件读取为数据库。连接字符串的提供程序指向 OLEDB.12.0 版本(而不是 4.0 版本),因为正在使用 Excel 2007。因此,Extended Properties 部分也不同。HDR 只是一个属性,指示 Excel 文件中的第一行用作标题(当设置为 Yes 时)。连接到 Excel 2003 或更早版本时,整个连接字符串将不同。使用 DataAdapter
填充 DataSet
,并将第一个表分配给 GridView
。就是这样。
实现“导入到 Excel”的另一种方法是使用 Excel Interop。这里不讨论这种方法。
GridView 中的下拉列表
在 GridView
中添加下拉列表也是一个相当常见的需求。
让我们先看一下 ASPX 代码。为了定义下拉列表,我们需要在代码中添加 ItemTemplate
s。前两列 Name 和 Age 将是简单的 DataBinders。第三个 ItemTemplate
将包含一个 DropDownList
。记住,AutoGenerateColumns
已设置为 false。到目前为止都很简单。
<columns>
<asp:templatefield headertext="Name">
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem, "Name")>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Age">
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem, "Age")>
</itemtemplate>
</asp:templatefield>
<asp:templatefield sortexpression="Occupation" headertext="Occupation">
<itemtemplate>
<asp:dropdownlist id="DropDownList1" runat="server">
</itemtemplate>
</asp:templatefield>
</columns>
这是用户在屏幕上看到的 UI
GridView
使用 DataTable
填充。这也很容易。
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
dt.Columns.Add("Occupation");
DataRow dr = dt.NewRow();
dr["Name"] = "Chris Harris";
dr["Age"] = "40";
dr["Occupation"] = "Doctor";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Sean Williams";
dr["Age"] = "39";
dr["Occupation"] = "Plumber";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Paul Newcombe";
dr["Age"] = "38";
dr["Occupation"] = "Lecturer";
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
现在 comes 稍微棘手的部分。为了填充 GridView
的 DropDownList
,我们需要遍历每一行并找到该行中的 DropDownList
。如果有一个静态 DataSource
,可以避免这种情况。然而,在这里,我们使用的是运行时生成的 DataSource
。我们找到 DropDownList
,然后将其绑定到同一个动态 DataSource 的 Occupation
列。
foreach (GridViewRow grdRow in GridView1.Rows)
{
DropDownList drdList =
(DropDownList)(GridView1.Rows[grdRow.RowIndex].Cells[1].FindControl(
"DropDownList1"));
drdList.DataSource = dt;
drdList.DataValueField = "Occupation";
drdList.DataTextField = "Occupation";
drdList.DataBind();
}
就是这样。我们现在在 GridView
中有一个 DropDownList
。我们可以使用类似的带有少量增强功能的代码和 EditTemplate
来在编辑模式下显示 DropDownList
,同时允许用户在正常模式下看到一个标签。
获取多个 DataKeys 的单个 DataKey 值
如果您有一个带有多个数据键名称的 GridView
,例如 DataKeyNames="targetid,RequestID"
,现在您想获取它们的单个值,您需要执行以下操作
string targetID= gv.DataKeys[e.RowIndex].Values[0].ToString();
string requestID= gv.DataKeys[e.RowIndex].Values[1].ToString();
您也可以使用
gv.DataKeys[e.SelectedIndex].Values["targetid"];
gv.DataKeys[e.SelectedIndex].Values["RequestID"];
这个问题被问了很多次,最近在 这里。
使用 EditItemTemplate 在 GridView 中显示 DropDownList
论坛上一个非常常见的问题是关于在 GridView
编辑时显示下拉列表。使用 EditItemTemplate
可以很容易地做到这一点。
UI 非常简单。显示一个 GridView
,第一列有一个 Edit 命令,然后是三列(Name、Age 和 Occupation),它们将保存数据。一旦用户单击“Edit”按钮,GridView
的 Occupation 列将显示。这是屏幕在网格处于编辑模式时外观的快照。
这是 UI 代码。注意 Edit CommandField
和 EditItemTemplate
的使用。当 GridView
不处于编辑模式时,会为这种情况使用普通的 ItemTemplate
。
<columns>
<asp:commandfield showeditbutton="True">
<asp:templatefield headertext="Name">
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem, "Name")>
</itemtemplate>
</asp:templatefield>
<asp:templatefield headertext="Age">
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem, "Age")>
</itemtemplate>
</asp:templatefield>
<asp:templatefield sortexpression="Occupation" headertext="Occupation">
<edititemtemplate>
<asp:dropdownlist id=""DropDownList1" runat="server">
</edititemtemplate>
<itemtemplate>
<%# DataBinder.Eval(Container.DataItem,"Occupation")>
</itemtemplate>
</asp:templatefield>
</columns>
让我们转到代码隐藏。这里有两个要点
第一个是要点是 DropDownList
的绑定必须在 GridView
的 RowDataBound
事件中进行,而不是在 RowEditing
事件中。RowEditingEvent
不理解 e.Row
。另外,RowDataBound
方法中的 if
条件很重要,特别是对 DataControlRowState
edit 的检查。这是因为 RowDataBound
每次 GridView
绑定时都会触发,而我们只想在编辑情况下处理我们的场景。
第二个要点(尽管与本示例不直接相关)是使用 RowEditing
事件。当 GridView
进入 Edit
模式时,这就是显示 DropDownList
的原因。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
(e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
DropDownList dl = (DropDownList)e.Row.FindControl("DropDownList1");
dl.DataSource = dt;
dl.DataValueField = "Occupation";
dl.DataTextField = "Occupation";
dl.DataBind();
}
}
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
GridView1.EditIndex = e.NewEditIndex;
GridView1.DataBind();
}
搞定了。这就是在 GridView
中显示 Edit
模式下的 DropDownList
的全部内容。
在 GridView 中显示图像
论坛上一个常见问题是如何在 GridView
中显示图像。ImageField
就足够了。下面是一个网页及其代码(在非常简单的场景下)的样子。
我们所要做的就是绑定到 DataImageUrlField
字段。请注意,项目中包含了一个(包含图像的)Images 文件夹。这将与页面一起托管在服务器上。
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("PictureUrl");
DataRow dr = dt.NewRow();
dr["Name"] = "Hydrangeas.jpg";
dr["PictureUrl"] = ResolveUrl("~/Images/Hydrangeas.jpg");
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Lighthouse.jpg";
dr["PictureUrl"] = ResolveUrl("~/Images/Lighthouse.jpg");
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
代码隐藏也相当容易理解。DataTable
作为 GridView
的源。请注意使用 ResolveUrl
方法来解析图像的路径。这就是在 GridView
中显示图像的全部内容。
在 GridView 中显示累计总计
在 GridView
中为一个数字字段计算累计总计是一个经常讨论的话题。这可以通过使用页脚模板轻松实现。看下面的 UI 和代码。
添加 ShowFooter = "true"
是显示 GridView
页脚的必要条件。FooterTemplate
负责其余部分。
代码隐藏利用 RowDataBound
方法进行求和。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
sum = sum + Convert.ToInt32(DataBinder.Eval(e.Row.DataItem, "Salary"));
}
if (e.Row.RowType == DataControlRowType.Footer)
{
Label obj = (Label)e.Row.FindControl("Sum");
obj.Text = Convert.ToString(sum);
}
}
总和在此方法中计算,然后最终分配给标签。这就是在页脚中显示总和的全部内容。
显示嵌套 GridView
显示嵌套 GridView
是一个相当常见的需求。使用 ItemTemplate
可以很容易地实现。UI 和代码如下所示。没什么可解释的——几个文本字段和两个网格(一个在另一个里面)。
这段代码被放入 Page_Load
事件中。
DataTable dt = new DataTable();
dt.Columns.Add("Name");
dt.Columns.Add("Age");
DataRow dr = dt.NewRow();
dr["Name"] = "Chris Harris";
dr["Age"] = "40";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Sean Williams";
dr["Age"] = "39";
dt.Rows.Add(dr);
dr = dt.NewRow();
dr["Name"] = "Paul Newcombe";
dr["Age"] = "38";
dt.Rows.Add(dr);
GridView1.DataSource = dt;
GridView1.DataBind();
foreach (GridViewRow grdRow in GridView1.Rows)
{
GridView nestedView = (GridView)(
GridView1.Rows[grdRow.RowIndex].Cells[2].FindControl("GridView2"));
nestedView.DataSource = dt;
//For a sample, rowindex is passed here.
//However, in a real environment, a key could
//be passed and this could fetch detail data
nestedView.DataSource = LoadNestedData(grdRow.RowIndex);
nestedView.DataBind();
}
LoadNestedData
是加载嵌套网格的方法。代码未在此处显示,但代码注释应提供此功能的作用的大致概念。嵌套 GridView
的 DataSource
是在运行时设置的。相当简单。
历史记录
- 添加于 2011/06/09:获取多个
DataKey
的单个DataKey
值。 - 添加于 2011/06/09:在
GridView
编辑模式下显示DropDownList
。 - 添加于 2011/09/10:在
GridView
中显示图像。 - 添加于 2011/09/12:导入 Excel 文件 / 显示累计总计。
- 添加于 2011/09/14:显示嵌套
GridView
。
我们持续征求读者的反馈。如果您希望我们包含其他主题,请随时在下面的评论部分发表。
我们将继续努力,不断更新本文档,加入来自问答和其他论坛的更常见的问题。