2011-07-14 39 views
3

我动态地创建一个包含数据和复选框的表,我的问题是当我检查一个特定的复选框被选中时,出了很多,它重置为假的默认状态(注:它不只是一个它不工作,其工作原理与所产生的复选框非)

表中的动态复选框将不会保留检查值

之前,我创建的Page_Load功能我创建的复选框,进一步向下创建表格,并填充数据,然后我设置了一个函数来检查点击以查看该盒子是否确实被检查,iv'e尝试了很多次迭代,没有运气

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

在那里你调用方法table_Builder – SMK

+0

使用[数据绑定的WebControl喜欢的GridView,中继器或ListView] (http://msdn.microsoft.com/en-us/library/ms228214.aspx)。 [Here](http://www.beansoftware.com/ASP.NET-Tutorials/Repeater-DataList-ListView-GridView.aspx)的概述。这让生活变得更轻松。 –

+0

@ shoaib,表生成器被调用另一个函数,我没有包括上面,我打电话给一个函数为sql – dweremeichik

回答

0

在加载视图状态并触发事件之前,将复选框添加到页面。在OnInit方法而不是onload中进行。使用Onload查看它们是否被选中。确保你给他们的ID。除非这是一个局部回传(阿贾克斯)则仅呈现选框的IsPostBack

1

因此,基本上这里发生的事情是,您每次页面加载时都会动态地将其放到页面上。因为您正在动态执行此操作,所以触发“已检查”事件的复选框或在回发期间检查的复选框不再存在,因为它不属于视图状态的一部分。 ASP.NET页面生命周期的工作方式是启动生命周期事件序列,而不管页面是否被回发,这意味着一个新的页面建立在你发起回发事件并且页面经过preinit,init,preload,load和所有爵士乐,然后它实际上击中任何事件处理代码。存在回发的页面有一组刚刚创建的复选框,它们与前一页上的复选框没有绑定关系。

你有几个选择这里,这里是他们两个:

有“检查”事件触发回传,并有对你在服务器上维护一个集检查Web控件的唯一ID。您可以通过中继器或gridview将控件拖放到页面上并挂接到其填充事件中。在此过程中,您可以添加刚刚添加到您存储在会话中的字典中的唯一ID,该字典保留了您希望从复选框到一段数据的任何关系。

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

这些都似乎像处理这个虽然漂亮毛茸茸的方式。如果你详细说明你需要什么,那么或许我可以给你一个更好的建议。

+0

如果用户被允许选择多个复选框,他们将不得不等待每次点击发送回传?管理一个隐藏的领域并不会更好。 –

+0

如何管理隐藏字段不是更好?任何时候,你都是通过代码隐藏动态填充一个页面的(如果你自己创建控件而不是使用数据绑定控件,ESPECIALLY),你将不得不跳过一些环节来将前面的交互 - 将数据填充到后端。复选框更棘手,因为您应该能够选择其中的一些。一种可以绕开的方法是在页面上放置一个checkButtonList,并动态地将创建的复选框添加到列表中。这应该是viewstate启用。 – MoarCodePlz

+0

在视图状态反序列化之前,@Dustin Davis建议将它们添加到页面,当视图状态反序列化时,复选框将接收它们的值。没有杂乱的箍试图跟踪身份证和什么不是。现在我认为使用checboxList会比单独的复选框好。 –

0

看来搜索后两天,我已经找到了一个不错的解决方案,更快,更容易比其他一些理解!;看起来,作为其他答案的状态,这是因为page_load,但是在这种情况下,init不是必需的,您只需重新创建所有控件,然后再执行其他任何操作。

该解决方案的关键在于:

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

凡在上面的代码中的注释是,在这里你调用创建所有控件,就像在我的例子是主要功能:
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> 
+2

你应该真正探索asp.net生命周期http://msdn.microsoft.com/en-us/library/ms178472.aspx。你所要做的就是在init中构建你的控件,而asp.net将完成剩下的工作。你让它变得比它更难。但是,如果这对你有用,那就这样吧。 –

+0

您的权利,我试着在不同的页面上面解决您的解决方案,它的工作更容易,现在我不得不回头修改我发布的网页,因为随着我解决它的方式,我遇到了实施新的主要问题特征 – dweremeichik