【问题标题】:Access HyperLink inside ItemTemplate inside TemplateField ASP.Net WebForms访问 TemplateField ASP.Net WebForms 内 ItemTemplate 内的 HyperLink
【发布时间】:2025-12-05 00:15:02
【问题描述】:

我在填充数据的 GridView 中有一个 ASP TemplateField,如下所示:

<asp:GridView ID="gvReport" runat="server" AutoGenerateColumns="False" ShowHeaderWhenEmpty="true" OnRowDataBound="gvReport_RowDataBound" CssClass="table table-bordered">
  <Columns>
    <asp:BoundField DataField="Delete" HeaderText="Delete" SortExpression="Delete" />
    <asp:TemplateField HeaderText="Delete">
      <ItemTemplate>
        <asp:HyperLink runat="server" NavigateUrl='<%# "Edit?from=Delete&ID=" + Eval("ID") %>' ImageUrl="Assets/SmallDelete.png" SortExpression="PathToFile" />
      </ItemTemplate>
    </asp:TemplateField>
  </Columns>
</asp:GridView>

换句话说,在每一行的末尾,都有一个删除“按钮”。我可以通过检查后面代码中 BoundField Delete 的真/假值来判断特定行/记录是否已被删除,如下所示:

  if (e.Row.RowType == DataControlRowType.DataRow)
    {
      TableCell statusCell = e.Row.Cells[0];

        if (statusCell.Text == "True")
        {
           //change ImageUrl of Hyperlink for this row
        }
     }

现在,我的删除图标是红色的,但是如果一条记录已经被删除, 我想将图像更改为不同的图标(蓝色图标)。

如果 statusCell 计算结果为 true,我如何更改此 ImageUrl?

【问题讨论】:

    标签: c# asp.net webforms


    【解决方案1】:

    好的,所以我们这里需要两个部分:

    我们需要(想要)持久化驱动网格的数据表)。

    这样做的原因是什么? 我们用一块石头杀死了大约 3 只鸟。

    我们使用数据表store/save/know the deleted state 我们使用该删除信息来切换我们的图像 (因此不必将状态存储在网格视图中)。

    我们还可以使用该表状态一次性更新数据库,因此不必编写一堆数据库操作(删除行)。我们只是将表发送回数据库。

    其实在这个例子中,我可以添加大约 7 行代码,如果你用 tab 键来编辑数据?它也将被发送回数据库。这意味着没有杂乱的编辑模板和所有的爵士乐(无论如何都是泛滥的)。

    好的,这里是我们的网格 - 只是一些酒店 - 以及带有图像的删除按钮:

    标记:

        <div style="width:40%;margin-left:20px">
          <asp:GridView ID="GridView1" runat="server" 
            AutoGenerateColumns="False" 
            DataKeyNames="ID" CssClass="table table-hover  borderhide" >
          <Columns>
    
            <asp:TemplateField  HeaderText="HotelName" >
                <ItemTemplate><asp:TextBox id="HotelName" runat="server" Text='<%# Eval("HotelName") %>' /></ItemTemplate>
            </asp:TemplateField>
    
            <asp:TemplateField  HeaderText="FirstName" SortExpression="ORDER BY FirstName" >
                <ItemTemplate><asp:TextBox id="FirstName" runat="server" Text='<%# Eval("FirstName") %>' /></ItemTemplate>
            </asp:TemplateField>
    
            <asp:TemplateField  HeaderText="LastName" >
                <ItemTemplate><asp:TextBox id="LastName" runat="server" Text='<%# Eval("LastName") %>' /></ItemTemplate>
            </asp:TemplateField>
    
           <asp:TemplateField  HeaderText="City" >
                <ItemTemplate><asp:TextBox id="City" runat="server" Text='<%# Eval("City") %>' /></ItemTemplate>
            </asp:TemplateField>
    
              <asp:TemplateField HeaderText="Delete">
                  <ItemTemplate>
                     <asp:ImageButton ID="cmdDelete" runat="server" Height="20px" Style="margin-left:10px"
                         ImageUrl="~/Content/cknosel.png" 
                         Width="24px" OnClick="cmdDelete_Click"></asp:ImageButton>
                  </ItemTemplate>
              </asp:TemplateField>
        </Columns>
    
          </asp:GridView>
            <br />
            <asp:Button ID="cmdDeleteAll" runat="server" Text="Delete selected" Width="122px"
                OnClientClick="return confirm('Delete all selected?')" />
        </div>
    

    好的,加载网格的代码 - 注意我们持久化数据表!!!!!

    代码:

        DataTable rstTable = new DataTable();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
                LoadGrid();
            else
                rstTable = (DataTable)ViewState["rstTable"];
        }
    
        void LoadGrid()
        {
            // load up our grid
            using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels ORDER BY HotelName ",
                new SqlConnection(Properties.Settings.Default.TEST4)))
            {
                cmdSQL.Connection.Open();
                rstTable.Clear();
                rstTable.Load(cmdSQL.ExecuteReader());
                GridView1.DataSource = rstTable;
                GridView1.DataBind();
            }
            ViewState["rstTable"] = rstTable;
        }
    

    好的,到目前为止,很简单的简。结果是这样的:

    好的,现在我们只需要添加删除按钮点击事件。

    该代码如下所示:

        protected void cmdDelete_Click(object sender, ImageClickEventArgs e)
        {
            ImageButton btn = (ImageButton)sender;
            GridViewRow rRow = (GridViewRow)btn.Parent.Parent;
            DataRow OneRow = rstTable.Rows[rRow.DataItemIndex];
    
            // toggle data
            if (OneRow.RowState == DataRowState.Deleted)
            {
                // undelete
                OneRow.RejectChanges();
                btn.ImageUrl = "/Content/cknosel.png";
            }
            else
            {
                // delete
                OneRow.Delete();
                btn.ImageUrl = "/Content/ckdelete.png";
            }
        }
    

    再一次,真的很简单。但请注意我们如何使用数据表的行状态(是否已删除)。

    这还切换了删除按钮的图像。

    因此,我们不必关心、担心或在网格中存储/保存状态。

    所以,如果我点击几行删除,我现在得到这个:

    到目前为止 - 很少的代码!!!

    好的,现在是最后一部分。整体删除选定的按钮。好吧,因为这很危险 - 请注意我是如何在 OnClientClick 事件中添加“确认删除”的。如果您点击取消,那么服务器端事件当然不会运行。

    但是,正如我们在持久化表格后所指出的那样?然后我们可以将删除的表直接发送回服务器而无需循环。因此删除代码如下所示:

        protected void cmdDeleteAll_Click(object sender, EventArgs e)
        {
            // send updates (deletes) back to database.
            using (SqlCommand cmdSQL = new SqlCommand("SELECT * from tblHotels WHERE ID = 0",
                new SqlConnection(Properties.Settings.Default.TEST4)))
            {
                cmdSQL.Connection.Open();
                SqlDataAdapter daUpdate = new SqlDataAdapter(cmdSQL);
                SqlCommandBuilder daUpdateBuild = new SqlCommandBuilder(daUpdate);
                daUpdate.Update(rstTable);
            }
            LoadGrid();  // refesh display
        }
    

    因此,请注意从数据库中更新(删除)是多么容易。如果你仔细看,我使用了那个网格的文本框——而不是标签。原因当然是如果用户在网格中使用选项卡(和编辑 - 非常像 excel),那么我可以用几行额外的代码将这些更改发送回数据库。事实上,上面的删除按钮代码在这里是 100% 相同的(它将与上面的代码一起发送表更改。所以,如果我们添加行,编辑行,那么上面并不是真正的删除命令,但实际上是我们的保存编辑/删除/添加命令!

    【讨论】: