从 RowDataBound 事件的 gridview 从单元格中获取值
Posted
技术标签:
【中文标题】从 RowDataBound 事件的 gridview 从单元格中获取值【英文标题】:Getting value from a cell from a gridview on RowDataBound event 【发布时间】:2010-09-12 09:53:10 【问题描述】:string percentage = e.Row.Cells[7].Text;
我正在尝试用我的 GridView 做一些动态的事情,所以我已经将一些代码连接到 RowDataBound 事件。我正在尝试从特定单元格中获取值,该单元格是 TemplateField。但是上面的代码似乎总是返回一个空字符串。
有什么想法吗?
为了澄清,这里有一点有问题的单元格:
<asp:TemplateField HeaderText="# Percentage click throughs">
<ItemTemplate>
<%# AddPercentClickThroughs((int)Eval("EmailSummary.pLinksClicked"), (int)Eval("NumberOfSends")) %>
</ItemTemplate>
</asp:TemplateField>
在相关说明中,有谁知道是否有更好的方法来选择行中的单元格。输入cell[1]
很糟糕。我不能cell["mycellname"]
,所以如果我决定改变我的单元格的顺序,错误就不会出现?
【问题讨论】:
您是否在每次回发时都进行数据绑定?你甚至有回发吗? 【参考方案1】:为什么不直接从数据源中提取数据。
DataBinder.Eval(e.Row.DataItem, "ColumnName")
【讨论】:
它不在数据源中,它是动态生成的,我已经编辑了我的问题以澄清 您的回答可能不适用于 OP 的问题,但它帮助了我。我试图获取 GridView 中 TemplateField 中包含的密码模式 TextBox 字段的值,因此我可以在 RowDataBound 上的 TextBox 中分配星号(默认行为是在密码模式 TextBoxes 中不显示任何内容)。 DataBinder.Eval() 成功了。 嘿,感谢我认识的这个疯狂的老人,但它对我帮助很大。 这显示了如何检索值 - 是否有类似的方法来修改和设置值?【参考方案2】:当您使用 TemplateField 并将文字文本绑定到它时,asp.net 实际上会为您插入一个控件!它被放入 DataBoundLiteralControl。如果您在获取空文本的代码行附近查看调试器,您可以看到这一点。
因此,要在不更改模板以使用控件的情况下访问信息,您可以像这样进行转换:
string percentage = ((DataBoundLiteralControl)e.Row.Cells[7].Controls[0]).Text;
这会让你得到你的文字!
【讨论】:
只是想对您的解决方案发表评论。我尝试了以下错误...“/WebSite2”应用程序中的服务器错误。 -------- 无法将“System.Web.UI.LiteralControl”类型的对象转换为“System.Web.UI.DataBoundLiteralControl”类型。异常详细信息:System.InvalidCastException:无法将“System.Web.UI.LiteralControl”类型的对象转换为“System.Web.UI.DataBoundLiteralControl”类型。源错误:第 68 行:Dim percent As String = DirectCast(e.Row.Cells(8).Controls(0), DataBoundLiteralControl).Text ......我错过了这是一个旧帖子。 嗨,克里斯,我想从 gridview 中获取我的第一列,我可以使用 -string percentage = ((DataBoundLiteralControl)e.Row.Cells[0].Controls[0]).Text;
或者我如何找到单元格和控件的索引!【参考方案3】:
以上是很好的建议,但是您可以在网格视图中获取单元格的文本值,而无需将其包装在文字或标签控件中。你只需要知道要连接什么事件。在这种情况下,请改用 DataBound 事件,如下所示:
protected void GridView1_DataBound(object sender, GridViewRowEventArgs e)
if (e.Row.RowType == DataControlRowType.DataRow)
if (e.Row.Cells[0].Text.Contains("sometext"))
e.Row.Cells[0].Font.Bold = true;
运行调试器时,您会看到此方法中出现文本。
【讨论】:
智能检查当前行是否为数据行【参考方案4】:首先,您需要将代码包装在Label
或Literal
控件中,以便您可以正确引用它。发生的情况是系统无法跟踪它,因为没有与文本关联的控件。将其内容添加到视图状态是控件的责任。
您需要使用 gridView.FindControl("controlName");获得行中的控制权。从那里你可以访问它的属性,包括Text
。
您还可以获取相关行的 DataItem 属性并将其转换为适当的类型并直接提取信息。
【讨论】:
但我实际上在单元格中没有控件(我知道!),我只是使用一种方法将字符串放入其中 您不需要将代码包装在标签或文字中。请参阅下面的答案。 周解,有更好的办法。【参考方案5】:例如,只需使用循环检查网格视图中的单元格:
for (int i = 0; i < GridView2.Rows.Count; i++)
string vr;
vr = GridView2.Rows[i].Cells[4].Text; // here you go vr = the value of the cel
if (vr == "0") // you can check for anything
GridView2.Rows[i].Cells[4].Text = "Done";
// you can format this cell
【讨论】:
【参考方案6】:使用RowDataBound
函数将数据与特定单元格绑定,并获得控制使用
(ASP 控件名称,如 DropDownList)GridView.FindControl("Name of Control")
【讨论】:
【参考方案7】:我有一个类似的问题,但通过稍微不同的方法找到了解决方案。我没有按照 Chris 的建议查找控件,而是首先更改了在 .aspx 页面中指定字段的方式。我没有使用<asp:TemplateField ...>
标签,而是将相关字段更改为使用<asp:BoundField ...>
。然后,当我到达 RowDataBound 事件时,可以直接访问单元格中的数据。
相关片段:一、aspx页面:
<asp:GridView ID="gvVarianceReport" runat="server" ... >
...Other fields...
<asp:BoundField DataField="TotalExpected"
HeaderText="Total Expected <br />Filtration Events"
htmlEncode="False" ItemStyle-HorizontalAlign="Left"
SortExpression="TotalExpected" />
...
</asp:Gridview>
然后在 RowDataBound 事件中我可以直接访问这些值:
protected void gvVarianceReport_Sorting(object sender, GridViewSortEventArgs e)
if (e.Row.Cells[2].Text == "0")
e.Row.Cells[2].Text = "N/A";
e.Row.Cells[3].Text = "N/A";
e.Row.Cells[4].Text = "N/A";
如果有人可以评论 为什么 这有效,我将不胜感激。我不完全明白为什么没有 BoundField 绑定后值不在单元格中,但您必须通过控件查找它。
【讨论】:
【参考方案8】:Label lblSecret = ((Label)e.Row.FindControl("lblSecret"));
【讨论】:
【参考方案9】:<asp:TemplateField HeaderText="# Percentage click throughs">
<ItemTemplate>
<%# AddPercentClickThroughs(Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "EmailSummary.pLinksClicked")), Convert.ToDecimal(DataBinder.Eval(Container.DataItem, "NumberOfSends")))%>
</ItemTemplate>
</asp:TemplateField>
public string AddPercentClickThroughs(decimal NumberOfSends, decimal EmailSummary.pLinksClicked)
decimal OccupancyPercentage = 0;
if (TotalNoOfRooms != 0 && RoomsOccupied != 0)
OccupancyPercentage = (Convert.ToDecimal(NumberOfSends) / Convert.ToDecimal(EmailSummary.pLinksClicked) * 100);
return OccupancyPercentage.ToString("F");
【讨论】:
【参考方案10】:如果您将 asp:BoundField 上的属性 Visible 设置为 False。像这样
<asp:BoundField DataField="F1" HeaderText="F1" Visible="False"/>
循环行时,您将不会在 Cells[i].Text 属性中获得任何文本。所以
foreach (GridViewRow row in myGrid.Rows)
userList.Add(row.Cells[0].Text); //this will be empty ""
但是您可以通过将网格连接到事件 OnRowDataBound 来设置不可见的列,然后从这里执行此操作
e.Row.Cells[0].Visible = false //now the cell has Text but it's hidden
【讨论】:
【参考方案11】:关于列的索引选择样式,我建议您执行以下操作。我遇到了这个问题,但我打算使用API
动态设置值,所以我所做的是:
请记住 .CastTo<T>
只是 ((T)e.Row.DataItem)
您必须致电DataBind()
才能查看网格中的更改。这样,如果您决定向网格中添加一列,就不会遇到问题。
protected void gvdata_RowDataBound(object sender, GridViewRowEventArgs e)
if(e.Row.RowType == DataControlRowType.DataRow)
var number = e.Row.DataItem.CastTo<DataRowView>().Row["number"];
e.Row.DataItem.CastTo<DataRowView>().Row["ActivationDate"] = DateTime.Parse(userData.basic_info.creation_date).ToShortDateString();
e.Row.DataItem.CastTo<DataRowView>().Row["ExpirationDate"] = DateTime.Parse(userData.basic_info.nearest_exp_date).ToShortDateString();
e.Row.DataItem.CastTo<DataRowView>().Row["Remainder"] = Convert.ToDecimal(userData.basic_info.credit).ToStringWithSeparator();
e.Row.DataBind();
【讨论】:
【参考方案12】:protected void gvbind_RowDataBound(object sender, GridViewRowEventArgs e)
if (e.Row.RowType == DataControlRowType.DataRow)
e.Row.Attributes["onmouseover"] = "this.style.cursor='hand';";
e.Row.Attributes["onmouseout"] = "this.style.textDecoration='none';";
e.Row.Attributes["onclick"] = ClientScript.GetPostBackClientHyperlink(this.gvbind, "Select$" + e.Row.RowIndex);
【讨论】:
以上是关于从 RowDataBound 事件的 gridview 从单元格中获取值的主要内容,如果未能解决你的问题,请参考以下文章
在GridView的RowDataBound事件中获取某行某列的值!