You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

按钮点击触发InvalidCastException:无法转换ContentPlaceHolder为GridViewRow

解决InvalidCastException:无法将ContentPlaceHolder转换为GridViewRow的问题

让我们先拆解你遇到的问题根源,再给出针对性的解决方案:

问题出在哪?

  1. 初始代码的核心错误:你写的GridViewRow gvr = (GridViewRow)(((Control)sender).NamingContainer);完全找错了对象来源。sender是btnSaveOpeningBalance按钮,这个按钮并不在GridView的行内部,它的命名容器(NamingContainer)是页面的ContentPlaceHolder,强行把它转换成GridViewRow必然抛出类型转换异常。
  2. 第二次尝试的错误:GridViewRow gvr = gvItem.Rows[gvItem.SelectedDataKey.Value];同样逻辑错误——SelectedDataKey.Value是你绑定的ItemID(一个int16类型的业务主键),而Rows集合需要的是行的索引值(int类型),而且如果用户没有选中任何行,SelectedDataKey还会是null,这又会引发新的空引用错误。

正确的解决方案

你的核心需求是遍历GridView的所有行,读取每行输入控件的值并插入数据库。直接利用循环变量i获取对应行即可,完全不需要从sender那里找行:

protected void btnSaveOpeningBalance_Click(object sender, EventArgs e) {
    try {
        AddItemBLL objAddItemsBll = new AddItemBLL();
        
        if (gvItem.Rows.Count > 0) {
            for(int i = 0; i < gvItem.Rows.Count; i++) {
                // 直接用循环变量i获取当前遍历的行
                GridViewRow gvr = gvItem.Rows[i];
                
                TextBox txtQuantity = (TextBox)gvr.FindControl("txtQuantity");
                double qty = string.IsNullOrWhiteSpace(txtQuantity.Text.Trim()) ? 0 : Convert.ToDouble(txtQuantity.Text.Trim());
                
                TextBox txtVal = (TextBox)gvr.FindControl("txtValue");
                double val = string.IsNullOrWhiteSpace(txtVal.Text.Trim()) ? 0 : Convert.ToDouble(txtVal.Text.Trim());
                
                // 每次循环新建一个SetItemDAO对象,避免覆盖之前行的数据
                SetItemDAO objItmDAOMaster = new SetItemDAO();
                objItmDAOMaster.ItemID = Convert.ToInt16(gvItem.DataKeys[i].Values["ItemID"]);
                objItmDAOMaster.ItmQty = qty;
                objItmDAOMaster.ItmVl = val;
                
                bool result = objAddItemsBll.InsertItemBalance(objItmDAOMaster);
                // 这里可以根据result做后续处理,比如记录插入状态、提示用户等
            }
        }
    } catch(Exception ex) {
        // 不要用throw ex; 会丢失原始堆栈信息,直接用throw;保留完整调试线索
        throw;
    }
}

额外优化建议

  • 用string.IsNullOrWhiteSpace()替代Text.Trim().Length > 0,更简洁且能处理全空白字符的情况。
  • 每次循环都新建SetItemDAO对象,否则所有行的数据都会被最后一行覆盖,导致插入的全是重复内容。
  • 异常处理中直接用throw;代替throw ex;,避免丢失原始异常的堆栈跟踪信息,方便后续调试。

内容的提问来源于stack exchange,提问作者Ehsan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:32:17