33
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"],所以如果我决定改变我的单元格的顺序,错误就不会出现?

4

12 回答 12

55

为什么不直接从数据源中提取数据。

DataBinder.Eval(e.Row.DataItem, "ColumnName")
于 2008-09-23T15:29:31.450 回答
23

当您使用 TemplateField 并将文字文本绑定到它时,asp.net 实际上会为您插入一个控件!它被放入 DataBoundLiteralControl。如果您查看获取空文本的代码行附近的调试器,您可以看到这一点。

因此,要在不更改模板以使用控件的情况下访问信息,您可以像这样进行转换:

string percentage = ((DataBoundLiteralControl)e.Row.Cells[7].Controls[0]).Text;

这会让你得到你的文字!

于 2008-10-07T18:50:40.587 回答
14

以上是很好的建议,但您可以在网格视图中获取单元格的文本值,而无需将其包装在文字或标签控件中。你只需要知道要连接什么事件。在这种情况下,请改用 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;
        }
    }
}

运行调试器时,您将看到此方法中出现的文本。

于 2009-04-10T15:46:18.297 回答
13

首先,您需要将代码包装在一个LabelLiteral控件中,以便您可以正确引用它。发生的情况是系统无法跟踪它,因为没有与文本关联的控件。将其内容添加到视图状态是控件的责任。

您需要使用 gridView.FindControl("controlName"); 获得行中的控制权。从那里你可以得到它的属性,包括Text.

您还可以获取相关行的 DataItem 属性并将其转换为适当的类型并直接提取信息。

于 2008-09-23T15:28:42.887 回答
6

只需使用循环来检查网格视图中的单元格,例如:

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 
    }
}
于 2011-03-30T19:39:57.927 回答
2

使用RowDataBound函数将数据与特定单元格绑定,并获取控件使用(ASP 控件名称,如 DropDownList)GridView.FindControl("Name of Control")

于 2011-04-06T17:23:46.510 回答
1

我有一个类似的问题,但通过稍微不同的方法找到了解决方案。我没有按照 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 绑定后值不在单元格中,但您必须通过控件查找它。

于 2012-09-27T16:33:52.713 回答
0
Label lblSecret = ((Label)e.Row.FindControl("lblSecret"));
于 2012-08-23T12:09:18.990 回答
0
<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");
}
于 2014-10-09T02:12:48.287 回答
0

如果将 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
于 2017-01-19T09:53:41.913 回答
0

关于列的索引选择样式,我建议您执行以下操作。我遇到了这个问题,但我打算使用 an 动态设置值,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();
            }
        }
于 2020-06-19T22:37:37.547 回答
-1
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);
    }
}
于 2015-04-05T04:39:48.260 回答