2

似乎很容易,但我很难做到这一点。

    <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)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 中找到超链接控件。

我收到以下错误,这对我来说没有意义

无法将“System.Web.UI.DataBoundLiteralControl”类型的对象转换为“System.Web.UI.WebControls.HyperLink”类型。

Update1 如果我不使用超链接字段,此代码可以顺利运行。

 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;
 }
                }
4

1 回答 1

2

首先要做的事情——你试图FindControl("id");在设计视图中控制你的实际位置ID——案例很重要。

另一件事 - 这似乎也是因为<a>它实际上不是一个HyperLink控件,但实际上是一个HtmlGenericControl- 因此试图施放你的控件不会导致任何结果。

你可以做两件事之一 - 改变你的代码隐藏以获得HtmlGenericControl link = (HtmlGenericControl )row.FindControl("ID");

或者更改您的设计视图并使用<asp:Hyperlink>控件而不是 HTML<a>

你的错误Unable to cast object of type 'System.Web.UI.DataBoundLiteralControl' (which is ain HTML terms) to type 'System.Web.UI.WebControls.HyperLink'.

是说((HyperLink)GridView1.Rows[i].Cells[0].Controls[0] 您处理的行上第一个单元格中位置 0 的控件是文字而不是链接。您可以尝试通过查看 Controls[1] 来伪造它。

您可以查看表格的呈现 HTML 并验证这一点 - 您的链接将嵌套在跨度中,或在跨度旁边..

检查Controlsin debug 并查看其中实际包含的内容。

更新

关于如何调用代码存在很多困惑。你有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只会查看控件中的直接控件。它不会在您的控件内的控件中找到控件 - IE 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");

一旦你有了控制权,你就可以把它转换成你需要/或应该的样子

于 2013-08-09T17:37:53.923 回答