单击提交按钮时,如何获取动态创建的复选框的值?

时间:2015-05-13 22:24:16

标签: c# asp.net viewstate

我有一个asp.net页面,上面有两个控件,一个占位符和一个提交按钮。在Page_Load期间,我动态创建任务清单。每行包含一个描述,指向教程的链接和一个复选框。该行中的所有信息都保存在数据库中。如果数据库说已检查任务,则代码会将checked属性设置为true。我遇到的问题是,当单击提交按钮时,我无法找到页面上所有复选框的已检查属性的值(总共约23个)。

以下是创建复选框的代码......

checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);

if (item.Attributes.Contains("ree_completed"))
checkbox.Checked = (bool)item.Attributes["ree_completed"];

checkbox.EnableViewState = true;
checkbox.ClientIDMode = System.Web.UI.ClientIDMode.Static;

checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();
checkbox.ID = checkboxId;

以下是尝试查找复选框值的代码...

foreach (Entity item in checklistCollection.Entities)
{
    checkboxId = "checkbox" + (string)item.Attributes["ree_sectionnumber"].ToString() + (string)item.Attributes["ree_sequencenumber"].ToString();

    itemChecked = (bool)ViewState[checkboxId];

    if (itemChecked == "true")
        ** update database **

     //CheckBox checkbox = (CheckBox)phchecklist.FindControl(checkboxId);
}

我想我已经阅读了关于这个主题的每一篇文章,并尝试了大部分内容。我也读过关于ViewState的内容,但我读过的建议没有用。正如您所看到的,我也尝试通过id找到控件集合中的复选框,但也无效。

回发到页面时,我不会重新创建复选框。有些帖子提到你必须重新创建控件但是当我尝试这样做时,我收到一条错误消息,说它是一个重复的id。我不希望重新创建页面的另一个原因是性能损失。该数据库位于远程的Microsoft Dynamic CRM数据库中。

如何在帖子后面保留checked属性的值?

更新:我更改了逻辑并修复了重复ID错误。该页面现在将在回发期间重新创建所有控件。单击提交按钮时,我仍然无法找到任何复选框控件的值。

加里

4 个答案:

答案 0 :(得分:0)

您需要在创建复选框控件时为其提供ID。由于您要创建多个复选框;一个用于数据库中的每一行...您需要将唯一的行标识符添加到ID。因此,您需要从行ID(通常是IDENTITY)构建复选框ID。示例:">

然后,当您对表中的每一行进行后处理时,在回发时,您可以查询该特定键值对的请求。类似的东西:

foreach(DataTable.Rows中的DataRow博士)     响应[" CHK _" + dr(" ID")];

答案 1 :(得分:0)

使用Page Init作为page_Load事件。根据{{​​3}}"使用此事件来读取或初始化控件属性"

答案 2 :(得分:0)

如果要工作,您需要为动态添加的控件添加事件处理程序 在你的情况下

checkbox = new CheckBox();
phChecklist.Controls.Add(checkbox);
checkbox.CheckedChanged += checkBox_CheckedChanged;

然后你需要在方法中做什么

private void CheckBox_CheckedChanged(object sender, System.EventArgs e)
{
  ...
}

答案 3 :(得分:0)

正如我评论的那样,你肯定需要在Init事件期间创建控件,Load太晚了。有关详细信息,请查看asp.Net page life's cycle

另外,您可能希望让ASP.NET处理控件的ID。你说你需要保留一些价值才能回到数据库,你可以wrap your checkboxes in a table。然后,您将能够遍历控件而无需猜测其名称。

例如,如果你的行有一个HiddenField,后跟你的实际CheckBox:

//Please call me during Init
protected void createTheControls() { 
    TableRow tr;
    TableCell td;
    CheckBox cb;
    HiddenField section, sequence;

    foreach (Object item in someList)
    {
        section = new HiddenField();
        section.Value = item.Attributes["ree_sectionnumber"].ToString();

        sequence = new HiddenField;
        sequence.Value = item.Attributes["ree_sequencenumber"].ToString();

        cb = new CheckBox();
        cb.ID = String.Concat("checkbox", (String)sequence.Value);
        if (item.Attributes.Contains("ree_completed"))
            cb.Checked = (bool)item.Attributes["ree_completed"];

            td = new TableCell();
            td.Controls.Add(section);
            td.Controls.Add(sequence);
            td.Controls.Add(cb);

            tr = new TableRow();
            tr.Cells.Add(td);
        }
    }

protected void readTheControls()
{
    foreach (TableRow tr in myTable.Rows)
    {
        HiddenField section = (HiddenField)tr.Cells[0].Controls[0];
        HiddenField sequence = (HiddenField)tr.Cells[0].Controls[1];
        CheckBox cb = (CheckBox)tr.Cells[0].Controls[2];
    }
}

我注意到你试图明确地使用ViewState,我相信这里没有任何帮助。上面的解决方案可能看起来很麻烦,但它确保您在获取控件时不需要弄乱ID。

这里是thorough explanation from MSDN,这里有few short and sweet SO answers解释ViewState的目的。