4

注意:我已更新此问题的代码以使示例更清晰,并利用下面 Karl Anderson 提供的示例代码。我也愿意接受其他方式来完成我需要完成的工作。

我正在创建一个包含多个复选框的表单,这些复选框可能会或可能不会被用于每个请求。我正在尝试在 DetailsView 网格中的这些复选框下方创建一个按钮,该按钮仅在需要检查所有复选框时才选中(而不是选中和取消选中的按钮)。正如您从下面的代码中看到的那样,在复选框周围有多个文本框/BoundFields,这些复选框包含此表单的各种类型的信息。没有增加“检查所有复选框”按钮复杂性的表单在前端和写入数据库时​​没有任何问题。

使用我面临的当前障碍下方的代码不仅让按钮一次只检查所有复选框,而且在页面加载时克服这个错误:

无法通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换将类型“System.Web.UI.WebControls.TableCell”转换为“System.Web.UI.WebControls.CheckBox”

根据我对类似(但不准确)错误的研究,我需要将复选框转换为其他形式。我以前从未遇到过这种情况,我不仅要寻找教育参考,而且要寻找一些关于如何解决转换部分的指针,以及关于如何解决的准确和最新的(在过去几年内)参考我可以解决按钮正确检查所有 19 个复选框的更大问题。

我在这里做错了什么,这是获得我想要的结果的正确方法吗?我不仅想学习如何解决这个问题,还想学习这个挑战背后的理论/逻辑,这样我就能以正确的方式学习它。

.aspx 代码。

(Note some cosmetic code for the details view has been omitted)


<%@ Page Title="Test Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="form2.aspx.cs" Inherits="form2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="FeaturedContent" Runat="Server">
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:DetailsView ID="DetailsView" runat="server" AutoGenerateColumns="False" CellPadding="4" DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None">
    <AlternatingRowStyle BackColor="White" />
    <insert asp cosmetic gobbledy gook here>
    <Fields>
        <asp:BoundField DataField="Field_1" HeaderText="Ticket Number" SortExpression="Field_1" />
        <asp:BoundField DataField="Field 2" HeaderText="Field 2" SortExpression="Field_2" />
        <asp:BoundField DataField="Field_3" HeaderText="Field 3" SortExpression="Field_3" />
        <asp:BoundField DataField="Field_4" HeaderText="Field 4" SortExpression="Field_4" />
        <asp:BoundField DataField="Field_5" HeaderText="Field 5" SortExpression="Field_5" />
        <asp:BoundField DataField="Field_6" HeaderText="Field 6" SortExpression="Field_6" />
        <asp:BoundField DataField="Field_7" HeaderText="Field 7" SortExpression="Field_7" />
        <asp:BoundField DataField="Field_8" HeaderText="Field 8" SortExpression="Field_8" />
        <asp:BoundField DataField="Field_9" HeaderText="Field 9" SortExpression="Field_9" />
        <asp:BoundField DataField="Field_10" HeaderText="Field 10" SortExpression="Field_10" />
        <asp:CheckBoxField DataField="Check_Box_1" HeaderText="Check Box 1" SortExpression="Check_Box_1" />
        <asp:CheckBoxField DataField="Check_Box_2" HeaderText="Check Box 2" SortExpression="Check_Box_2" />
        <asp:CheckBoxField DataField="Check_Box_3" HeaderText="Check Box 3" SortExpression="Check_Box_3" />
        <asp:CheckBoxField DataField="Check_Box_4" HeaderText="Check Box 4" SortExpression="Check_Box_4" />
        <asp:CheckBoxField DataField="Check_Box_5" HeaderText="Check Box 5" SortExpression="Check_Box_5" />
        <asp:CheckBoxField DataField="Check_Box_6" HeaderText="Check Box 6" SortExpression="Check_Box_6" />
        <asp:CheckBoxField DataField="Check_Box_7" HeaderText="Check Box 7" SortExpression="Check_Box_7" />
        <asp:CheckBoxField DataField="Check_Box_8" HeaderText="Check Box 8" SortExpression="Check_Box_8" />
        <asp:CheckBoxField DataField="Check_Box_9" HeaderText="Check Box 9" SortExpression="Check_Box_9" />
        <asp:CheckBoxField DataField="Check_Box_10" HeaderText="Check Box 10" SortExpression="Check_Box_10" />
        <asp:CheckBoxField DataField="Check_Box_11" HeaderText="Check Box 11" SortExpression="Check_Box_11" />
        <asp:CheckBoxField DataField="Check_Box_12" HeaderText="Check Box 12" SortExpression="Check_Box_12" />
        <asp:CheckBoxField DataField="Check_Box_13" HeaderText="Check Box 13" SortExpression="Check_Box_13" />
        <asp:CheckBoxField DataField="Check_Box_14" HeaderText="Check Box 14" SortExpression="Check_Box_14" />
        <asp:CheckBoxField DataField="Check_Box_15" HeaderText="Check Box 15" SortExpression="Check_Box_15" />
        <asp:CheckBoxField DataField="Check_Box_16" HeaderText="Check Box 16" SortExpression="Check_Box_16" />
        <asp:CheckBoxField DataField="Check_Box_17" HeaderText="Check Box 17" SortExpression="Check_Box_17" />
        <asp:CheckBoxField DataField="Check_Box_18" HeaderText="Check Box 18" SortExpression="Check_Box_18" />
        <asp:CheckBoxField DataField="Check_Box_19" HeaderText="Check Box 19" SortExpression="Check_Box_19" />


        <asp:ButtonField ButtonType="Button" CommandName="btnSelectAll" Text="Select/Check All Servers"


        <asp:BoundField DataField="Field_11" HeaderText="Field 11" SortExpression="Field_11" />
        <asp:BoundField DataField="Field_12" HeaderText="Field 12" SortExpression="Field_12" />
        <asp:BoundField DataField="Field_13" HeaderText="Field 13" SortExpression="Field_13" />

        <asp:CommandField ButtonType="Button" NewText="CreateRecord" ShowInsertButton="True" />
    </Fields>
    <more asp non essential cosmetic gobbledy gook>

        </asp:DetailsView>
        <asp:SqlDataSource ID="SqlDataSource1" ConnectionString="<%$ ConnectionStrings:test_form_connect %>" runat="server" InsertCommand="INSERT INTO [test].[detailsview_test_form] ([Field_1], [Field_2], [Field_3], [Field_4], [Field_5], [Field_6], [Field_7], [Field_8], [Field_9], [Field_10], [Check_Box_1], [Check_Box_2], [Check_Box_3], [Check_Box_4], [Check_Box_5], [Check_Box_6], [Check_Box_7], [Check_Box_8], [Check_Box_9], [Check_Box_10], [Check_Box_11], [Check_Box_12], [Check_Box_13], [Check_Box_14], [Check_Box_15], [Check_Box_16], [Check_Box_17], [Check_Box_18], [Check_Box_19], [Field_11], [Field_12], [Field_13]) VALUES (@Field_1, @Field_2, @Field_3, @Field_4, @Field_5, @Field_6, @Field_7, @Field_8, @Field_9, @Field_10, @Check_Box_1, @Check_Box_2, @Check_Box_3, @Check_Box_4, @Check_Box_5, @Check_Box_6, @Check_Box_7, @Check_Box_8, @Check_Box_9, @Check_Box_10, @Check_Box_11, @Check_Box_12, @Check_Box_13, @Check_Box_14, @Check_Box_15, @Check_Box_16, @Check_Box_17, @Check_Box_18, @Check_Box_19, @Field_11, @Field_12, @Field_13) ">

        <InsertParameters>
    <asp:Parameter Name="Field_1" />
    <asp:Parameter Name="Field_2" />
    <asp:Parameter Name="Field_3" />
    <asp:Parameter Name="Field_4" />
    <asp:Parameter Name="Field_5" />
    <asp:Parameter Name="Field_6" />
    <asp:Parameter Name="Field_7" />
    <asp:Parameter Name="Field_8" />
    <asp:Parameter Name="Field_9" />
    <asp:Parameter Name="Field_10" />
    <asp:Parameter Name="Check_Box_1" />
    <asp:Parameter Name="Check_Box_2" />
    <asp:Parameter Name="Check_Box_3" />
    <asp:Parameter Name="Check_Box_4" />
    <asp:Parameter Name="Check_Box_5" />
    <asp:Parameter Name="Check_Box_6" />
    <asp:Parameter Name="Check_Box_7" />
    <asp:Parameter Name="Check_Box_8" />
    <asp:Parameter Name="Check_Box_9" />
    <asp:Parameter Name="Check_Box_10" />
    <asp:Parameter Name="Check_Box_11" />
    <asp:Parameter Name="Check_Box_12" />
    <asp:Parameter Name="Check_Box_13" />
    <asp:Parameter Name="Check_Box_14" />
    <asp:Parameter Name="Check_Box_15" />
    <asp:Parameter Name="Check_Box_16" />
    <asp:Parameter Name="Check_Box_17" />
    <asp:Parameter Name="Check_Box_18" />
    <asp:Parameter Name="Check_Box_19" />
    <asp:Parameter Name="Field_11" />
    <asp:Parameter Name="Field_12" />
    <asp:Parameter Name="Field_13" />

            </InsertParameters>
            </asp:SqlDataSource>


</asp:Content>

.....和cs代码:

using System;
using System.Configuration;
using System.Collections;
using System.Data;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

public partial class form2 : System.Web.UI.Page    
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
    foreach (Details
        if (e.CommandName == "btnSelectAll")
        {
        DetailsViewRow row = DetailsView1.Rows[9];
        (row.Cells[10] as CheckBox).Checked = true; 
        DetailsViewRow row1 = DetailsView1.Rows[10];
        (row1.Cells[11] as CheckBox).Checked = true;
        DetailsViewRow row2 = DetailsView1.Rows[11];
        (row.Cells[12] as CheckBox).Checked = true;
        DetailsViewRow row3 = DetailsView1.Rows[12];
        (row.Cells[13] as CheckBox).Checked = true;
        DetailsViewRow row4 = DetailsView1.Rows[13];
        (row.Cells[14] as CheckBox).Checked = true;
        DetailsViewRow row5 = DetailsView1.Rows[14];
        (row.Cells[15] as CheckBox).Checked = true;
        DetailsViewRow row6 = DetailsView1.Rows[15];
        (row.Cells[16] as CheckBox).Checked = true;
        DetailsViewRow row7 = DetailsView1.Rows[16];
        (row.Cells[17] as CheckBox).Checked = true;
        DetailsViewRow row8 = DetailsView1.Rows[17];
        (row.Cells[18] as CheckBox).Checked = true;
        DetailsViewRow row9 = DetailsView1.Rows[18];
        (row.Cells[19] as CheckBox).Checked = true;
        DetailsViewRow row10 = DetailsView1.Rows[19];
        (row.Cells[20] as CheckBox).Checked = true;
        DetailsViewRow row11 = DetailsView1.Rows[20];
        (row.Cells[21] as CheckBox).Checked = true;
        DetailsViewRow row12 = DetailsView1.Rows[21];
        (row.Cells[22] as CheckBox).Checked = true;
        DetailsViewRow row13 = DetailsView1.Rows[22];
        (row.Cells[23] as CheckBox).Checked = true;
        DetailsViewRow row14 = DetailsView1.Rows[23];
        (row.Cells[24] as CheckBox).Checked = true;
        DetailsViewRow row15 = DetailsView1.Rows[24];
        (row.Cells[25] as CheckBox).Checked = true;
        DetailsViewRow row16 = DetailsView1.Rows[25];
        (row.Cells[26] as CheckBox).Checked = true;
        DetailsViewRow row17 = DetailsView1.Rows[26];
        (row.Cells[27] as CheckBox).Checked = true;
        DetailsViewRow row18 = DetailsView1.Rows[27];
        (row.Cells[28] as CheckBox).Checked = true;
        DetailsViewRow row19 = DetailsView1.Rows[28];
        (row.Cells[29] as CheckBox).Checked = true;



    }
}   
}
4

7 回答 7

1

这是未经测试的,但应该可以工作,所以试试这个:

protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
    // Use the CommandName property to determine which button
    // was clicked. 
    if (e.CommandName == "btnSelectAll")
    {
        // You may need to tweak this as I almost never use DetailsView, but the concept should work
        // Check the Apples checkbox
        // Apples is the first row (index 0) and second cell (index 1)
        DetailsViewRow row = DetailsView1.Rows[0];
        (row.Cells[1] as CheckBox).Checked = true;

        // Check the Oranges checkbox
        // Apples is the second row (index 1) and second cell (index 1)
        DetailsViewRow row = DetailsView1.Rows[1];
        (row.Cells[1] as CheckBox).Checked = true;

        // Keep moving through the rows...
    }

}
于 2013-06-29T02:25:41.150 回答
1

尝试使用客户端脚本作为

$(".btnClass").click(function(){
$(".chkBoxClass").attr("checked", "checked");
});

其中 btnClass 是按钮的类,chkBoxClass 是复选框的通用类。

于 2013-06-29T21:10:33.103 回答
1

您通过引用转换、装箱转换、拆箱转换、包装转换或空类型转换获得“'System.Web.UI.WebControls.CheckBox'”的原因是因为您试图将 Cell 转换为 CheckBox。

请注意,我在行单元格的 ControlCollection 中找到了 CheckBox 控件。

以下是经过测试的有效示例代码:

形式:

    <asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="None" OnItemCommand="DetailsView1_ItemCommand">
<AlternatingRowStyle BackColor="White" />
<Fields>
    <asp:ButtonField ButtonType="Button" CommandName="btnSelectAll" Text="Select/Check All Servers" />
    <asp:ButtonField ButtonType="Button" CommandName="btnEdit" Text="Edit" />
    <asp:ButtonField ButtonType="Button" CommandName="btnCancel" Text="Cancel" />
    <asp:ButtonField ButtonType="Button" CommandName="btnSave" Text="Save" />
    <asp:CommandField ButtonType="Button" NewText="CreateRecord" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>

代码背后:

    DataTable m_table = null;

    public DataTable table
    {
        get
        {
            if (ViewState["m_table"] != null)
                return (DataTable)ViewState["m_table"];
            else
                return null;
        }
        set
        {
            ViewState["m_table"] = value;
        }
    }


    public static T FindControl<T>(ControlCollection controls)
    {
        for (int i = 0; i < controls.Count; i++)
        {
            if (controls[i] is T)
                return (T)(object)controls[i];
        }

            return default(T);
    }


    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            table = new DataTable();

            DataColumn col1 = new DataColumn("Field_1");
            DataColumn col11 = new DataColumn("Check_Box_1");
            DataColumn col12 = new DataColumn("Check_Box_2");
            DataColumn col13 = new DataColumn("Check_Box_3");

            col1.DataType = System.Type.GetType("System.String");
            col11.DataType = System.Type.GetType("System.Boolean");
            col12.DataType = System.Type.GetType("System.Boolean");
            col13.DataType = System.Type.GetType("System.Boolean");

            table.Columns.Add(col1);
            table.Columns.Add(col11);
            table.Columns.Add(col12);
            table.Columns.Add(col13);

            DataRow row = table.NewRow();
            row[col1] = "1";
            row[col11] = false;
            row[col12] = false;
            row[col13] = false;

            table.Rows.Add(row);

            DetailsView1.DataSource = table;
            DetailsView1.DataBind();
        }

    }

    protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
    {
        if (e.CommandName == "btnSelectAll")
        {
            foreach (DetailsViewRow row in DetailsView1.Rows)
            {
                for (int i = 0; i < row.Cells.Count; i++)
                {
                    CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
                    if (cb != null)
                    {
                        cb.Checked = true;
                    }                        
                }                    
            }
        }
        if (e.CommandName == "btnSave")
        {
            int j = 0;
            foreach (DetailsViewRow row in DetailsView1.Rows)
            {
                for (int i = 0; i < row.Cells.Count; i++)
                {
                    TextBox tb = FindControl<TextBox>(row.Cells[i].Controls);
                    if (tb != null)
                    {
                        table.Rows[0][j] = tb.Text;
                    }

                    CheckBox cb = FindControl<CheckBox>(row.Cells[i].Controls);
                    if (cb != null)
                    {
                        table.Rows[0][j] = cb.Checked;
                    }
                }
                j++;
            }

            DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
            DetailsView1.DataSource = table;
            DetailsView1.DataBind();
        }
        if (e.CommandName == "btnEdit")
        {
            DetailsView1.ChangeMode(DetailsViewMode.Edit);
            DetailsView1.DataSource = table;
            DetailsView1.DataBind();
        }
        if (e.CommandName == "btnCancel")
        {
            DetailsView1.ChangeMode(DetailsViewMode.ReadOnly);
            DetailsView1.DataSource = table;
            DetailsView1.DataBind();
        }
    }
于 2013-07-31T00:46:46.267 回答
1

如果您在类似代码中设置断点row.Cells[0]并查看Controls属性(在快速观察窗口或其他调试窗口之一中),您应该能够找到相关的CheckBoxes并弄清楚如何从每个单元格向下遍历它们。

但是,这应该让您觉得这是一个非常糟糕的主意。现在,您的代码与页面结构紧密耦合。这对你来说将很难保持下去,而且从事这个项目的其他任何人都可能会花费很长时间来解决这个问题。这段代码需要扔掉。

如果您需要在表单上包含这么多字段,请考虑将这些字段完全分离到单独的页面上,并实际在页面本身上单独创建字段。您可能认为这对用户来说会花费更多时间,但老实说——这个表单有 13 个参数和 19 个CheckBoxes。这是一种复杂的形式,需要特别小心和注意。

最后,您(和其他开发人员)在改进此页面和修复错误时节省的时间将很快为用户带来回报。

于 2013-07-31T16:29:05.930 回答
0

根据卡尔安德森的回答:

protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
    if (e.CommandName == "btnSelectAll")
    {
        foreach (DetailsViewRow row in DetailsView1.Rows)
        {
            (row.Cells[1].Controls[0] as CheckBox).Checked = true;
        }
    }

}

不确定这是否可以解决所有问题,但需要将其拉入循环,我相信Controls[0]会处理复选框。

于 2013-07-24T22:10:18.593 回答
0

我会尝试:

protected void DetailsView1_ItemCommand(Object sender, DetailsViewCommandEventArgs e) {
  if (e.CommandName == "btnSelectAll") {
    var controls = new Stack<Control>();
    controls.Push(DetailsView1);
    while (controls.Count > 0) {
      var control = controls.Pop();
      var checkbox = control as CheckBox;
      if (checkbox != null) {
        checkbox.Checked = true;
      }
      foreach (Control childControl in control.Controls) {
        controls.Push(childControl);
      }
    }
  }
}

循环遍历子控件甚至可以在不同的控件类型上工作。

于 2013-07-26T15:16:10.317 回答
0

好的,所以您只需更改此行即可访问该复选框:

(row.Cells[10] as CheckBox).Checked = true;

到这一行:

(row.Cells[10].Controls[0] as CheckBox).Checked = true;

包含一组TableCell实际用于呈现 UI 的控件。CheckBoxField在集合中的第一个控件的情况下是CheckBox.

现在,为了使这段代码更具可扩展性,我可以这样做:

if (e.CommandName == "btnSelectAll")
{
    for (int i = 9; i < 29; i++)
    {
        DetailsViewRow row = DetailsView1.Rows[i];
        (row.Cells[i + 1].Controls[0] as CheckBox).Checked = true; 
    }
于 2013-07-31T11:58:10.667 回答