表中的动态复选框不会保持选中的值

时间:2011-07-14 20:18:23

标签: c# asp.net

我动态创建一个包含数据和复选框的表,我的问题是当我检查一个特定的复选框被选中时,在很多情况下,它会重置为默认状态false(注意:它不是只有一个它无法使用,它适用于非生成的复选框)

在我创建page_load函数之前,我创建了复选框,进一步向下创建表,并用数据填充它,然后我设置了一个函数来检查点击是否确实检查了框,iv'我尝试了很多迭代,没有运气

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
    //  
}

3 个答案:

答案 0 :(得分:1)

所以基本上这里发生的是每次页面加载时你都会动态地将它放到页面上。因为您是动态执行此操作,所以触发“已检查”事件或在回发期间检查的复选框不再存在,因为它不是视图状态的一部分。 ASP.NET页面生命周期的工作方式是触发生命周期事件序列,无论页面是否被回发,这意味着在您触发回发事件并且页面通过时构建新页面preinit,init,preload,load,以及爵士在实际点击任何事件处理代码之前的所有内容。回发中存在的页面具有一组新创建的复选框,这些复选框与前一页上的复选框没有绑定。

这里有几个选项,其中有两个:

让'checked'事件触发回发,并根据您在服务器上维护的集合检查Web控件的唯一ID。您可以通过转发器或gridview将控件放到页面上并挂钩到其填充事件中。在这样做时,您可以添加刚刚添加到字典中的控件的唯一ID,该字典存储在会话中,该会话可以将复选框中所需的任何关系维护到一段数据。

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

这两个看起来都像是处理这个问题的方法。如果你详细说明你需要什么,那么也许我可以给你一个更好的建议。

答案 1 :(得分:0)

在加载视图状态并触发事件之前,将复选框添加到页面。在OnInit方法而不是onload中执行。使用Onload查看是否已选中。一定要给他们ID。除非这是部分回发(ajax),否则只显示复选框if IsPostback

答案 2 :(得分:0)

经过两天的搜索,我发现一个非常好的解决方案比其他一些解决方案更快更容易理解;看来,正如其他答案所述,这是因为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>