看起来很容易,但我很难做到这一点。
<asp:TemplateField HeaderText="ID" InsertVisible="False" SortExpression="id">
<ItemTemplate>
<a href="/visit.aspx?Id=<%#Eval("Id")%>" id="ID" name="ID"> <%#Eval("Id")%> </a>
</ItemTemplate>
</asp:TemplateField>
gridview的最后一列有一个按钮。单击此按钮更新数据库并刷新 gridview。它还查看 gridview 中的 id 列并尝试突出显示已编辑的行。
如果 ID 字段是有界字段并且不是 URL,则代码可以正常工作。但是当它是一个 URL 时,我似乎无法读取 URL 的文本值。我尝试了各种解决方案(来自SO和在线的帮助)
HyperLink link = (HyperLink)row.FindControl("id");//没有工作
((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]).Text//不起作用
这是我需要帮助的代码片段
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
if (row.RowType == DataControlRowType.DataRow)
{
HyperLink link = (HyperLink)row.FindControl("id");
if (((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]).Text == button.CommandName)
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
}
我正在使用button.CommandName来存储ID字段,效果很好。我似乎无法在模板字段内的 gridview 中找到超链接控件。
我收到以下错误,这对我来说没有意义
Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' to type 'System.Web.UI.WebControls.HyperLink'.
更新1 如果我不使用超链接字段,此代码可以顺利运行。
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
if (row.Cells[0].Text.Equals(button.CommandName))
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
如果将第0列改为超链接并更改相应的代码,则不起作用。显然读取错误的单元格不是问题。
for (int i = 0; i < GridView1.Rows.Count; i++)
{
GridViewRow row;
row = GridView1.Rows[i];
HtmlAnchor anchor = (HtmlAnchor) row.Cells[0].Controls[0];
if ( anchor.InnerText.Equals(button.CommandName))
{
row.BackColor = System.Drawing.Color.IndianRed;
}
}
最佳答案
首先要做的事情 - 您正在尝试 FindControl("id");
设计 View 中的控件实际上是 ID
- 大小写很重要。
另一件事 - 这似乎也是因为 <a>
实际上不是HyperLink
控制,但实际上是HtmlGenericControl
- 因此尝试施放你的控制不会产生任何结果。
您可以执行以下两件事之一 - 更改代码隐藏以获取 HtmlGenericControl link = (HtmlGenericControl )row.FindControl("ID");
或者更改您的设计 View 并使用 <asp:Hyperlink>
控件而不是 HTML <a>
您的错误Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' (which is a
in HTML terms) to type 'System.Web.UI.WebControls.HyperLink'.
意思是((HyperLink)GridView1.Rows[i].Cells[0].Controls[0]
您处理的行第一个单元格中位置 0 处的控件是文字而不是链接。您可以尝试通过查看 Controls[1] 来伪造它。
您可以查看表格的渲染 HTML 并验证这一点 - 您的链接将嵌套在跨度中或跨度旁边。
检查Controls
在调试中查看其中实际包含的内容。
更新
对于如何调用代码存在很多困惑。您有e.Row.RowType
这让我相信你正在 RowDataBound
中这样做.
如果是这种情况,那么您不需要循环遍历所有 gridview 行,因为该方法会在每一行上调用 - 因此您将调用每一行,然后调用网格中的每一行..大量的循环正在进行一个大网格。
所以试试这个 - 它只对这一行感兴趣。
另外 - 不确定你从哪里得到你的 button.CommandName
来自
为此,您需要检查 FindControl 方法以确保它实际上是一个超链接控件
if ((e.Row.RowType == DataControlRowType.DataRow)) {
GridViewRow row = e.Row;
// get your link - if indeed the control IS a hyperlink
// this will be null if the control "id" is NOT a hyperlink control
HyperLink link = (HyperLink)row.FindControl("id");
if ((link.Text == Button.CommandName)) {
row.BackColor = Drawing.Color.IndianRed;
}
}
上次更新...
好的 - 经过更多评论后,我认为您需要递归搜索控件。这是因为FindControl
只会查看控件内的直接控件。它不会在您的控件内的控件内查找控件 - I.E FindControl 仅查看第一个子级,而不是孙级。
所以在你喜欢的地方创建这个方法:
public static Control FindControlRecursive(Control Root, string Id)
{
if (Root.ID == Id) { return Root; }
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null) { return FoundCtl; }
}
return null;
}
然后传入您的行和您要查找的控件的 ID。
就像这样 - 改变:
HyperLink link = (HyperLink)row.FindControl("id");
对此 - 请注意我保留了你的小写字母 id
- 不确定您使用的是小写还是大写 - 此方法将为您找出小问题:)
Control link = FindControlRecursive(row, "id");
一旦你掌握了控制权,你就可以将其转换到你需要/或应该的地方
关于asp.net - 获取位于 GridView 中模板字段内的超链接的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18152401/