【问题标题】:How to get any column value of selected row with checkbox in gridview without iterating?如何在不迭代的情况下在gridview中使用复选框获取所选行的任何列值?
【发布时间】:2016-08-05 15:18:42
【问题描述】:

我有一个 gridview,它从 SQL Server 2014 的数据库中获取数据。gridview 有四列来自数据库 (p_id, p_image, p_name, p_price),后面是 2 个附加列,一个下拉列表和一个复选框,下面有一个文本框网格视图。

我的要求是当我选中复选框时,所选行的价格列中的值与下拉列表控件中的值相乘并显示在文本框中。

当我再次选中另一个复选框时,我希望将此选定行的价格列的值与其下拉列表值相乘,并添加到文本框的前一个值并显示在同一个文本框中。我使用的代码是:

public double sum = 0 ; 

protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
        foreach (GridViewRow row in gvPackaged.Rows)
        {
            CheckBox chk = (row.Cells[5].FindControl("chkSelect") as CheckBox);
            DropDownList ddl = (row.Cells[4].FindControl("ddlSelect") as DropDownList);
            if (row != null && chk != null)
            {
                if (chk.Checked)
                {
                    double quantity = Convert.ToDouble(ddl.Text);
                    double price = Convert.ToDouble(row.Cells[3].Text);
                    sum += (price * quantity);
                    tbTotal.Text = Convert.ToString(sum);
                }
            }
        }
}

代码正在运行,但问题是每次我选中复选框时,都会调用 onCheckedChanged 方法,它会遍历 gridview 中的所有行,然后在文本框中显示值,这使得过程相当缓慢.

我在包括这个论坛在内的许多论坛中进行了搜索,发现几乎每个问题和答案都使用了这种方法。

唯一的其他方法是:

GridViewRow row = myGridview.SelectedRow;

而不是

foreach (GridViewRow row in myGridview.Rows)

因此我在我的代码中使用了它:

public double sum = 0 ; 

protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
        GridViewRow row = gvPackaged.SelectedRow;
        CheckBox chk = (row.Cells[5].FindControl("chkSelect") as CheckBox);         //HERE
        DropDownList ddl = (row.Cells[4].FindControl("ddlSelect") as DropDownList);

        if (row != null && chk != null)
        {
            if (chk.Checked)
            {
                double quantity = Convert.ToDouble(ddl.Text);
                double price = Convert.ToDouble(row.Cells[3].Text);
                sum += (price * quantity);
                tbTotal.Text = Convert.ToString(sum);
            }
        }
}

然后在//HERE这一行上面的代码中出现了这个错误:

NullReferenceException

这意味着上面一行中的行变量发生了异常,并且

对象引用未设置为对象的实例。

我再次搜索它,发现它是一个普遍的例外,并没有找到特定于我的问题的解决方案。

任何人都可以帮助我将当前选定的行检索到row 变量中,以便我可以直接使用该行执行计算,而无需使用循环和迭代。

【问题讨论】:

  • sender 参数是CheckBox,因此您不必尝试查找它,而是使用CheckBox chk = (CheckBox)sender;。它的父控件是GridViewRow,因此您应该能够使用它来查找DropDownList 并仅针对该行执行计算而无需迭代。

标签: c# asp.net gridview checkbox nullreferenceexception


【解决方案1】:

试试这个:

GridViewRow row=(sender as CheckBox).Parent.Parent as GridViewRow;

或者这个:

CheckBox cb = (CheckBox)sender;
GridViewRow row = (GridViewRow)cb.NamingContainer;
if (row != null)
{
   ...
}

【讨论】:

    【解决方案2】:

    默认情况下,嵌入在 GridView(按钮、DDL)中的交互式服务器控件可以触发回发。如果您启用 GridView 行选择,也会由于事件冒泡而导致回发。

    您需要所有这些回发吗? 一般来说......可能不会,除非你在后面的代码中做一些改变 GridView 内容的事情

    如果您的 GridView 的每一行都有一个 ddl,在选择时,该 ddl 将乘以同一行上的价格,并且位于网格之后的文本框用于保存累积,您可以非常快速地完成所有这些客户端一个非常小的 jquery,或者一个稍微大一点的 javascript。

    考虑一下这个 GridView 标记:

        <asp:GridView ID="GridView1" runat="server" 
          ClientIDMode="Predictable"
          DataSourceID="SqlDataSource1" >
          <Columns>
            <asp:BoundField DataField="p_price" HeaderText="p_price" SortExpression="p_price"></asp:BoundField>
            <asp:TemplateField>
              <ItemTemplate>
                <div class="parent-div">
                  <input type="checkbox" ID="CheckBox1" runat="server" />
                  <asp:DropDownList ID="ddl_qty" runat="server" AutoPostBack="false">
                    <asp:ListItem Text="1" Value="1"></asp:ListItem>
                    <asp:ListItem Text="2" Value="2"></asp:ListItem>
                    <asp:ListItem Text="3" Value="3"></asp:ListItem>
                  </asp:DropDownList>
                </div>
              </ItemTemplate>
            </asp:TemplateField>
          </Columns>
        </asp:GridView>
    
        <asp:TextBox ID="tbxTotal" runat="server" 
            ClientIDMode="Static"></asp:TextBox>
    

    还有这个RowDataBound事件在后面的代码中,对不起VB:

        Private Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
          If e.Row.RowType = DataControlRowType.DataRow Then
            Dim drv As DataRowView = e.Row.DataItem
    
            Dim ddl_qty As DropDownList = e.Row.FindControl("ddl_qty")
            ddl_qty.Attributes("data-associated-price") = drv("p_price")
    
            Dim CheckBox1 As HtmlInputCheckBox = e.Row.FindControl("CheckBox1")
            CheckBox1.Attributes("data-associated-ddl") = String.Format("#{0}", ddl_qty.ClientID)
            CheckBox1.Attributes("onclick") = "CalculateTotal()"
          End If
        End Sub
    

    这是客户端 Jquery 进行计算

      function CalculateTotal() {
        var total = 0.0;
    
        $(".parent-div").each(function(i, e) {
          var $cbx = $(this).find("input:checkbox");
    
          if ($cbx.is(":checked")) {
            var ddl_id = $cbx.attr("data-associated-ddl")
            var $ddl = $(ddl_id);
            var p = parseFloat($ddl.attr("data-associated-price"));
            var q = parseFloat($ddl.val());
            total += (p * q);
          }
        });
    
        $('#tbxTotal').val(total);
      }
    

    在这个 sn-p 中,html 是由上面的代码生成的,并注意执行计算的 jquery。请注意,我不会重新计算选择更改,但也可以在后面的代码中轻松添加。

    function CalculateTotal() {
      var total = 0.0;
    
      $(".parent-div").each(function(i, e) {
        var $cbx = $(this).find("input:checkbox");
    
        if ($cbx.is(":checked")) {
          var ddl_id = $cbx.attr("data-associated-ddl")
          var $ddl = $(ddl_id);
          var p = parseFloat($ddl.attr("data-associated-price"));
          var q = parseFloat($ddl.val());
          total += (p * q);
        }
      });
    
      $('#tbxTotal').val(total);
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <table cellspacing="0" rules="all" border="1" id="cphMain_GridView1" style="border-collapse:collapse;">
      <tbody>
        <tr>
          <th scope="col">p_price</th>
          <th scope="col">&nbsp;</th>
        </tr>
        <tr>
          <td>10.000000</td>
          <td>
            <div class="parent-div">
              <input name="ctl00$cphMain$GridView1$ctl02$CheckBox1" 
                     type="checkbox" id="cphMain_GridView1_CheckBox1_0" 
                     data-associated-ddl="#cphMain_GridView1_ddl_qty_0" 
                     onclick="CalculateTotal()">
              <select name="ctl00$cphMain$GridView1$ctl02$ddl_qty" 
                      id="cphMain_GridView1_ddl_qty_0" 
                      data-associated-price="10.000000">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
    
              </select>
            </div>
          </td>
        </tr>
        <tr>
          <td>10.220000</td>
          <td>
            <div class="parent-div">
              <input name="ctl00$cphMain$GridView1$ctl03$CheckBox1" 
                     type="checkbox" id="cphMain_GridView1_CheckBox1_1" 
                     data-associated-ddl="#cphMain_GridView1_ddl_qty_1" 
                     onclick="CalculateTotal()">
              <select name="ctl00$cphMain$GridView1$ctl03$ddl_qty" 
                      id="cphMain_GridView1_ddl_qty_1" 
                      data-associated-price="10.220000">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
    
              </select>
            </div>
          </td>
        </tr>
        <tr>
          <td>10.480000</td>
          <td>
            <div class="parent-div">
              <input name="ctl00$cphMain$GridView1$ctl04$CheckBox1" 
                     type="checkbox" 
                     id="cphMain_GridView1_CheckBox1_2" 
                     data-associated-ddl="#cphMain_GridView1_ddl_qty_2" 
                     onclick="CalculateTotal()">
              <select name="ctl00$cphMain$GridView1$ctl04$ddl_qty" 
                      id="cphMain_GridView1_ddl_qty_2" 
                      data-associated-price="10.480000">
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
    
              </select>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
    <input name="ctl00$cphMain$tbxTotal" type="text" id="tbxTotal">

    所有计算都在客户端完成,完成后您可以通过一个按钮进行回发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-11
      • 2012-03-06
      • 2014-07-14
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 2012-09-23
      • 2012-07-08
      相关资源
      最近更新 更多