表中的动态复选框不能保存选中的值

本文关键字:保存 复选框 动态 不能 | 更新日期: 2023-09-27 18:02:02

我正在动态创建一个包含数据和复选框的表,我的问题是当我检查一个特定的复选框被选中时,在许多情况下,它重置为默认状态false(注意:它不仅仅是一个它不工作,它与非生成的复选框一起工作)

在我创建page_load函数之前,我创建了一个复选框,然后我创建了一个表,并用数据填充它,然后我设置了一个函数来检查点击,看看这个框是否确实被选中了,我已经尝试了很多次,但都没有运气

protected void  table_builder(SqlDataReader readerinfo)
{
    //Create a new step for the user
    step3label.Text = "3.";
    //Table header
    TableHeaderRow hr = new TableHeaderRow();
    TableHeaderCell hc = new TableHeaderCell();
    TableHeaderCell hc2 = new TableHeaderCell();
    TableHeaderCell hc3 = new TableHeaderCell();
    hr.Cells.Add(hc);
    hc.Text = "ID"; //Assign header 1 with a name
    hr.Cells.Add(hc2);
    hc2.Text = "Name";//Assign header 2 with a name
    hr.Cells.Add(hc3);
    hc3.Text = "Selection";
    Table1.Rows.Add(hr);

    //Dynamic Table Generation
    int numcells = 3;
    int triswitch = 0;//this is use to chose which cell is made, id, name or selection
    string checkboxID = null;

    while (readerinfo.Read())   //execute the following aslong as there is data to fill the table with
    {
        for (int j = 0; j < 1; j++)
        {
            TableRow r = new TableRow();
            for (int i = 0; i < numcells; i++)
            {
                TableCell c = new TableCell();
                switch (triswitch)
                {
                    case 0: // this case sets the info for the feild id
                        c.Text = readerinfo.GetSqlGuid(0).ToString();
                        checkboxID = readerinfo.GetSqlGuid(0).ToString();
                        r.Cells.Add(c);
                        triswitch = 1;
                        break;
                    case 1:
                        c.Text = readerinfo.GetString(1);
                        r.Cells.Add(c);
                        triswitch = 2;
                        break;
                    case 2:
                        Checkbox_creator(checkboxID,ref c);
                        r.Cells.Add(c);
                        triswitch = 0;
                        break;
                }
            }
            Table1.Rows.Add(r);
        }
    }       
}
protected void Checkbox_creator(string id,ref TableCell send)
{
    //create the checbox
    ckbx = new CheckBox();
    ckbx.ID = "CBX" + checkboxid.ToString();
    checkboxid++;
    ckbx.InputAttributes.Add("value", id);
    send.Controls.Add(ckbx); //add the chekbox to the cell
    checkboxidlist.Add(id);//add the id of the checkbox to the list 
}

//
//AFTER DATATABLE IS LOADED
//
public void test()
{
    // Find control on page.
    CheckBox myControl1 = (CheckBox)Table1.FindControl("CBX0");
    if (myControl1 != null)
    {
        // Get control's parent.
        Control myControl2 = myControl1.Parent.Parent.Parent;
        Response.Write("Parent of the text box is : " + myControl2.ID);
        if (myControl1.Checked == true)
        {
            Response.Write("check box checked");
        }
    }
    else
    {
        Response.Write("Control not found");
    }
}
 //on Submit button click, execute the following function
protected void Submit_Click(object sender, EventArgs e)
{
    //Code to be executed
    string Userinput; //declare Userinput variable
    Userinput = Searchbox.Value; // Set variable to asp controll        
    Response.Write("<br /> <br />"+ Userinput +" <- user imput works");
    ConnectToSql(Userinput);//insert what the user submitted into a query
    test();
    //
    //
    //NoTe code validation is needed to prevent injections
    //  
}

表中的动态复选框不能保存选中的值

所以基本上这里发生的是你在每次页面加载时动态地将这个放到页面上。由于您是动态地执行此操作,因此触发"已检查"事件或在回发期间被检查的复选框将不再存在,因为它不再是视图状态的一部分。ASP。. NET页面生命周期的工作原理是触发生命周期事件序列,而不管页面是否被发回,这意味着在您触发回发事件的基础上构建新页面,并且页面在实际遇到任何事件处理代码之前要经历preinit、init、preload、load等一系列过程。为回发而存在的页面有一组新创建的复选框,这些复选框与上一页上的复选框没有绑定。

这里有几个选项,下面是其中的两个:

让'checked'事件触发回发,并根据服务器上维护的集合检查web控件的唯一ID。您可以通过repeater或gridview将控件拖放到页面上,并钩入其填充事件。通过这样做,您可以将刚刚添加到Dictionary中的控件的唯一ID添加到会话中,该会话维护从复选框到数据段的任何关系。

使用Javascript更新一个始终在页面上且启用了viewstate的隐藏字段。在这样做的过程中,您可以使用某种带分隔符的字符串来包含您认为与"已选中"复选框相关的信息。每次选中复选框时,将其标识信息添加到隐藏输入字段的值中,然后当回发触发时,您应该能够检查隐藏输入的值并从那里做任何您需要做的事情。

这两个似乎都是处理这个问题的非常棘手的方法。如果你能详细说明你需要什么,也许我能给你一个更好的建议。

在加载视图状态和触发事件之前将复选框添加到页面中。在OnInit方法中做,而不是在onload中。使用Onload来查看它们是否被选中。一定要给他们身份证。IsPostback

除非是部分回发(ajax),否则只在以下情况下呈现复选框

经过两天的搜索,我找到了一个非常好的解决方案,比其他一些更快,更容易理解;似乎其他答案的状态,这是因为page_load,但在这种情况下,init是不需要的,你只需要重新创建所有的控件之前,你可以做任何其他事情。

这个解决方案的关键是:

protected void RecreatePreviousState()
{
    if (this.IsPostBack)
    {
        //code to recreate
    }       
}

上面代码中的注释所在的地方,就是你调用创建所有控件的main函数的地方,就像我的例子一样:
ConnectToSql(Searchbox.Value)下面将是与此页相关的所有代码,供将来有此问题的任何人参考。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Data;

public partial class codebehind : System.Web.UI.Page 
{
//DECLARATIONS    
string selectedvalue;
List<string> createdckbxs = new List<string>();
List<string> CheckedCheckboxes = new List<string>();
CheckBox ckbx;
int ckbxID = 0;
//END DECLARATIONS

protected void Page_Load(object sender, EventArgs e)
{
    Response.Write(DateTime.Now); //local time -- testing
    Response.Write("<br /><br />NOTE: the id feild in the below table will be useless soon, it is only for testing purposes, look at CRM<br /><br />");
    selectedvalue = Request.QueryString["filter"];
    //88888888888888888
    RecreatePreviousState();
    //88888888888888888
    Response.Write(selectedvalue);
    instructionsfunc();
}

protected void instructionsfunc()
{
    switch (selectedvalue)
    {
        case "Name":
            instructions.Text = "Please enter the first few letters of the company you are looking for, ex. for "some company", you might search som";
            break;
        case "State":
            instructions.Text = "Please enter the abreviation of the state you are looking for, ex. for New York, enter NY";
            break;
    }
}

protected string sqlSelector(string uinput)
{
    switch (selectedvalue) //create the sql statments
    {
        case "Name":          
            return "SELECT [id],[name] FROM [asd].[jkl] WHERE [name] LIKE '" + uinput + "%' and [deleted] = 0 ORDER BY [name] ASC";  
        case "State":
            return "SELECT [id],[name] FROM [asd].[jkl] WHERE [shipping_address_state] LIKE '" + uinput + "%' and [deleted] = 0 ORDER BY [name] ASC";
        default:
            Response.Redirect("errorpage.aspx?id=002");
            return null; 
    }
}

//on Submit button click, execute the following function NOTE THIS BUTTON's ONLY USE IS POSTBACK
protected void Submit_Click(object sender, EventArgs e)
{
    string Userinput; //declare Userinput variable
    Userinput = Searchbox.Value; // Set variable to asp controll        
    Response.Write("<br /> <br />"+ Userinput +" <- user imput works");
}
//on Clear button click execute the following function
protected void Clear_Click(object sender, EventArgs e)
{
    Response.Redirect(Request.RawUrl);
}

protected void ConnectToSql(string input)
{
    System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
    //Todo add any aditional data needed to connection
    conn.ConnectionString = ConfigurationManager.ConnectionStrings["SplendidTestConnectionString"].ConnectionString;
    try
    {
        conn.Open();
        //this is the actual sql, this gets the data
        SqlCommand sqlString2 = new SqlCommand();
        sqlString2.CommandText = sqlSelector(input);
        sqlString2.CommandTimeout = 15;
        sqlString2.CommandType = System.Data.CommandType.Text;
        sqlString2.Connection = conn;
        SqlDataReader reader;
        reader = sqlString2.ExecuteReader();
        table_builder(reader);

        reader.Close(); //close the sql data reader

    }
    catch (Exception e)
    {
        //Some sort of redirect should go here to prevent the user from vewing a broken page
        conn.Close();
        //Response.Redirect("errorpage.aspx?id=001");
        Response.Write(e);
    }
    finally
    {
        if (conn.State != System.Data.ConnectionState.Closed)
        {
            conn.Close();//close up the connection after all data is done being populated
        }
    }
}
protected void  table_builder(SqlDataReader readerinfo)
{
    //Create a new step for the user
    step3label.Text = "3.";
    //Table header
    TableHeaderRow hr = new TableHeaderRow();
    TableHeaderCell hc = new TableHeaderCell();
    TableHeaderCell hc2 = new TableHeaderCell();
    TableHeaderCell hc3 = new TableHeaderCell();
    hr.Cells.Add(hc);
    hc.Text = "ID"; //Assign header 1 with a name
    hr.Cells.Add(hc2);
    hc2.Text = "Name";//Assign header 2 with a name
    hr.Cells.Add(hc3);
    hc3.Text = "Selection";
    Table1.Rows.Add(hr);

    //Dynamic Table Generation
    int numcells = 3;
    int triswitch = 0;//this is use to chose which cell is made, id, name or selection

    while (readerinfo.Read())   //execute the following aslong as there is data to fill the table with
    {
        for (int j = 0; j < 1; j++)
        {
            TableRow r = new TableRow();
            for (int i = 0; i < numcells; i++)
            {
                TableCell c = new TableCell();
                switch (triswitch)
                {
                    case 0: // this case sets the info for the feild id
                        c.Text = readerinfo.GetSqlGuid(0).ToString();
                        //RENAME THIS To ADDING BUTTON = readerinfo.GetSqlGuid(0).ToString();
                        r.Cells.Add(c);
                        triswitch = 1;
                        break;
                    case 1:
                        c.Text = readerinfo.GetString(1);
                        r.Cells.Add(c);
                        triswitch = 2;
                        break;
                    case 2:
                        ckbx = new CheckBox();
                        ckbx.ID = "CBX" + ckbxID;
                        createdckbxs.Add(ckbx.ID);
                        c.Controls.Add(ckbx);                           
                        r.Cells.Add(c);
                        triswitch = 0;
                        ckbxID++;
                        break;
                }
            }
            Table1.Rows.Add(r);
        }
    }
}

//
//AFTER DATATABLE IS LOADED
//   
protected void RecreatePreviousState()
{
    if (this.IsPostBack)
    {
        ConnectToSql(Searchbox.Value);
        MergeBtnCreate();
    }       
}
protected void MergeBtnCreate()
{
    Button MergeBTN = new Button();
    MergeBTN.Text = "Merge";
    MergeBTN.Click += new EventHandler(MergeBTN_Click);
    MergeBTNHolder.Controls.Add(MergeBTN);
}
void MergeBTN_Click(object sender, EventArgs e)
{
    foreach(string id in createdckbxs)
    {
        CheckBox myControl1 = (CheckBox)Table1.FindControl(id);
        if (myControl1 != null)
        {
            if (myControl1.Checked == true)
            {
                CheckedCheckboxes.Add(id);
            }
        }
        else
        {
            Response.Redirect("errorpage.aspx?id=003");
        }
    }
}
}


Asp.net

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="codebehind.aspx.cs" Inherits="codebehind" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Hello</title>
</head>
<body>
<form id="form1" runat="server">
        <div style="background-color:#55aaff;margin-bottom:10px;padding:5px;">
        <h3 style="padding:2px;margin:0px;">
            2.
        </h3>
        <asp:Label ID="instructions" runat="server" />
        <asp:Label ID="buttonclicked" runat="server" />
        <br />       
        <input id="Searchbox" type="text" runat="server" />
        <br />
        <asp:Button ID="SubmitBTN" runat="server" OnClick="Submit_Click" Text="Submit" />
        <asp:Button ID="ClearBTN" runat="server" OnClick="Clear_Click" Text="Clear" />
    </div>
    <div>
        <h3 style="padding:2px;margin:0px;">
            <asp:Label ID="step3label" runat="server" Text=""></asp:Label>
        </h3>
        <asp:Table ID="Table1" runat="server" GridLines="Both" />
    </div>
    <div>
        <asp:PlaceHolder ID="MergeBTNHolder" runat="server"></asp:PlaceHolder>
    </div>

</form>
</body>
</html>