当前位置:  开发笔记 > 后端 > 正文

ViewState和动态删除的控件

如何解决《ViewState和动态删除的控件》经验,为你挑选了1个好方法。

ASP.NET页面ViewState似乎很难跟上动态删除的控件及其中的值.

我们以下面的代码为例:

ASPX:

CS:

protected void Page_Init(object sender, EventArgs e) {
    Button b = new Button();
    b.Text = "Add";
    b.Click +=new EventHandler(buttonOnClick);
    form1.Controls.Add(b);
    Button postback = new Button();
    postback.Text = "Postback";
    form1.Controls.Add(postback);
}

protected void Page_Load(object sender, EventArgs e) {
    if (ViewState["controls"] != null) {
        for (int i = 0; i < int.Parse(ViewState["controls"].ToString()); i++) {
            controls.Controls.Add(new TextBox());
            Button remove = new Button();
            remove.Text = "Remove";
            remove.Click +=new EventHandler(removeOnClick);
            controls.Controls.Add(remove);
            controls.Controls.Add(new LiteralControl("
")); } } } protected void removeOnClick(object sender, EventArgs e) { Control s = sender as Control; //A hacky way to remove the components around the button and the button itself s.Parent.Controls.Remove(s.Parent.Controls[s.Parent.Controls.IndexOf(s) + 1]); s.Parent.Controls.Remove(s.Parent.Controls[s.Parent.Controls.IndexOf(s) - 1]); s.Parent.Controls.Remove(s.Parent.Controls[s.Parent.Controls.IndexOf(s)]); ViewState["controls"] = (int.Parse(ViewState["controls"].ToString()) - 1).ToString(); } protected void buttonOnClick(object sender, EventArgs e) { if (ViewState["controls"] == null) ViewState["controls"] = "1"; else ViewState["controls"] = (int.Parse(ViewState["controls"].ToString()) + 1).ToString(); controls.Controls.Add(new TextBox()); }

然后,假设您创建了4个控件并插入以下值:

[ 1 ] [ 2 ] [ 3 ] [ 4 ]

我们要删除第二个控件; 删除第二个控件后输出为:

[ 1 ] [ 3 ] [ 4 ]

这就是我们想要的.不幸的是,在随后的PostBack中,列表变为:

[ 1 ] [ ] [ 3 ]

所以,我的问题是,为什么会发生这种情况?据我所知,ViewState应该保存控件的属性与其索引相关,而不是实际控件.



1> Ruslan..:

几件事.是否通过其ID或索引加载控件取决于ViewStateModeById属性.默认情况下,它为false(表示按索引加载).

但是,文本框的处理方式不同.除非它们被禁用或不可见,否则它们的视图状态不包含输入值.text属性会被使用其ID的已发布值覆盖.由于您不管理文本框ID,因此会发生这种情况.

添加四个控件后,您有四个文本框:ctrl0,ctrl1,ctrl2和ctrl3,其值分别为1,2,3和4.

接下来,删除ctrl1框,客户端获取三个框:ctrl0,ctrl2和ctrl3,具有相应的值.现在,当您进行任何回发时,这三个值将以ctrl0 = 1&ctrl2 = 3&ctrl3 = 4的形式提交.

然后,在Page_Load上,创建三个控件,这次:ctrl0,ctrl1,ctrl2没有值.

Framework调用LoadRecursive来加载视图状态,然后调用ProcessPostData来分配输入值.它看到提交的ctrl0和ctrl2,找到具有相同id的控件并为它们赋值1和3.它没有找到ctrl3,所以它会跳过它.剩下的ctrl1只执行任何值的w/o.

例如,考虑这个解决方案(不是最好的):

protected void Page_Init(object sender, EventArgs e)
{
    Button b = new Button();
    b.Text = "Add";
    b.Click += new EventHandler(buttonOnClick);
    form1.Controls.Add(b);

    Button postback = new Button();
    postback.Text = "Postback";
    form1.Controls.Add(postback);
}

protected void Page_Load(object sender, EventArgs e)
{
    if (ViewState["controls"] != null)
    {
        List ids = (List)ViewState["controls"];

        for (int i = 0; i < ids.Count; i++)
        {
            TextBox textbox = new TextBox();
            textbox.ID = string.Format("txt_{0}", ids[i]);
            textbox.Text = textbox.ID;
            controls.Controls.Add(textbox);

            Button remove = new Button();
            remove.Text = "Remove";
            remove.Click += new EventHandler(removeOnClick);
            remove.ID = ids[i];
            controls.Controls.Add(remove);

            controls.Controls.Add(new LiteralControl("
")); } } } protected void removeOnClick(object sender, EventArgs e) { Control btn = sender as Control; List ids = (List)ViewState["controls"]; ids.Remove(btn.ID); //A hacky way to remove the components around the button and the button itself btn.Parent.Controls.Remove(btn.Parent.Controls[btn.Parent.Controls.IndexOf(btn) + 1]); btn.Parent.Controls.Remove(btn.Parent.Controls[btn.Parent.Controls.IndexOf(btn) - 1]); btn.Parent.Controls.Remove(btn); ViewState["controls"] = ids; } protected void buttonOnClick(object sender, EventArgs e) { List ids; if (ViewState["controls"] == null) ids = new List(); else ids = (List)ViewState["controls"]; string id = Guid.NewGuid().ToString(); TextBox textbox = new TextBox(); textbox.ID = string.Format("txt_{0}", id); textbox.Text = textbox.ID; controls.Controls.Add(textbox); Button remove = new Button(); remove.Text = "Remove"; remove.Click += new EventHandler(removeOnClick); remove.ID = id; controls.Controls.Add(remove); controls.Controls.Add(new LiteralControl("
")); ids.Add(id); ViewState["controls"] = ids; }

推荐阅读
手机用户2502852037
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有