各位仁兄,小弟用asp.net2.0做一程序,页面中有一个下拉框(值固定),根据下拉框选择值不同,动态地创建一些checkbox,radionbutton,同时也会对这些动态的控件做一些改变。请问在页面回传时,如何使这些动态的控件保存下来(包括其值,有可能在创建后被改变)。我在网上找了一些,好像用SaveViewState和LoadViewState,但是好像其改变的值无法保存下来。请问哪位大哥能帮忙解决一下。谢谢!!!分不够我再开!

解决方案 »

  1.   

    牺牲点性能吧
    把生成代码丢在pageLoad里 每次都生成 
    不然不能用FindControl找到该控件的
      

  2.   

    值用viewstate存起来,回传时在赋上
      

  3.   

    1楼,每次在page_load写,但是对于改后的值是要获得的,现在这个也是一个大问题。
    2楼,当单击确定铵钮时,页面回传,在页面重新加载之后才会执行铵钮响应事件,但是此时,动态创建的控件已经丢失。
      

  4.   

    to 楼上;
    动态创建的checkbox等后,可以对它的选中情况进行改变。这不就是它的值吗?至于你说的在事件发生之前就保存下来,我不知道如何做。请你明示,谢谢(我用的是asp.net2.0)
      

  5.   

    比如:
    你动态创建了一个CheckBox
    CheckBox ckb = new Check();
    ckb.id = "ckb1";
    panel.add(ckb);在button事件中:
    btn_Click (...)
    CheckBox ckb = this.FindControl("ckb1");
    string a = ckb.selectVelue;
    Session["a"] = a;
    这样不就保存下来了么。。
      

  6.   

    背后的原理参考这里,我懒得再打一次了:
    http://cathsfz.sitesled.com/2006/04/loadpostdata.htm解决方案:
    1.在动态更改控件创建的代码里(例如第一次创建控件的代码里),不仅仅要创建控件,还要将控件的多少、名称保存到ViewState里面。例如创建了5个checkbox,而这5个checkbox名称按顺序为checkbox0到checkbox4,那么你保存5就行了。但如果5个checkbox的名称完全没联系的,那就要把他们的名称也保存到ViewState里。
    2.在Page_Load里面,检测ViewState,然后根据ViewState的值创建相同的控件。例如上面的第一种情况,拟从ViewState读取到一个5出来,那就动态创建checkbox0到checkbox4,并且确保它们在控件树的位置与原来一致,那就行了。在LoadPostData的过程完了之后,这些控件会自动加载回PostBack回来的值,因为它们和上一次创建的空间有同样的UniqueID。
      

  7.   

    楼上的:
        谢谢你,这种方式效率很低,其中还有一个问题没有解决,就是我说的如果checkbox或radiobutton的值改变了(指的是重新选择了)无法获得。
      

  8.   

    to:redwolf_123(雨恨云愁) 
    你说的在button_click事件中,这时页面已经回传了,动态创建的控件已经不在了,如果你不相信你可以试一试。谢谢各位!!!
      

  9.   

    要把动态创建控件的代码放在 PageLoad里。。
      

  10.   

    to楼上的
    asp.net2.0的回传规则是最后执行button的单击事件。你好好想想!!!
      

  11.   

    我明白你的意思。 可是你不妨一试。
    你会很神奇的发现。。  虽然PageLoad再次赋值,可赋值无效
    取得的是你想要的传过来的那个值 呵呵
      

  12.   

    代码这么写
    private void Page_Load(object sender, System.EventArgs e)
    {
    // 在此处放置用户代码以初始化页面
    TextBox txt = new TextBox();
    txt.ID = "ckb1";
    txt.Text = "44";
    this.Panel1.Controls.Add(txt);
    } private void Button1_Click(object sender, System.EventArgs e)
    {
    TextBox txt = (TextBox)this.FindControl("ckb1");
    string a = txt.Text;
    Response.Write("a");
    }
      

  13.   

    你会发现 虽然每次页面都给text赋值了。。
    可是你却可以获得改变的那个文本里的值
    仔细去想想这是为什么:)
      

  14.   

    可能你没有理解我的意思,按照我那样做控件是能够正常取到最新PostBack的值的。关键的地方,是在Page_Load中检查ViewState并之前因为控件事件而创建控件的过程,由于创建控件的过程提前到了Page_Load,所以在进行第二次LoadPostData时这批控件将能够成功的加载本次PostBack回来的值。只有第一次动态创建是在Button_Click中发生,之后的都是在Page_Load中发生,这是重点。
      

  15.   

    由于动态创建的控件在页面回传的时候无法保存,故需要用ViewState保存其信息,在创建的时候增加代码
            Dim ckb As New CheckBox
            ckb.ID = "ckb1"
            ckb.Attributes("onclick") = "javacript:document.all.hidden1.value=document.all.ckb1.checked; alert(document.all.hidden1.value);"
            Panel1.Controls.Add(ckb)        Dim a(2) As String
            a(0) = "CheckBox"
            a(1) = "ckb1"
            ViewState("Ckb") = a
    上面的代码增加了一个隐藏域,用来通过点击动态创建的CheckBox的Checked值。
    前台加<input type="hidden" id="hidden1" runat="server">
    后台加Protected WithEvents Button1 As System.Web.UI.WebControls.Button然后再页面的PageLoad中加入
            Dim a(3) As String
            a = ViewState("Ckb")
            a(2) = hidden1.Value
            ViewState("Ckb") = a        If a(0) = "CheckBox" Then
                Dim ckb As New CheckBox
                ckb.ID = a(1)
                ckb.Checked = CBool(a(2))
                Panel1.Controls.Add(ckb)
            End If
    由隐藏域的值来获得回传前CheckBox的值,并通过ViewState来重新创建CheckBox,并赋值。
      

  16.   

    动态创建控件应该在Page_Init()完成。
    这样的好处是在Page_Load()中控件tb的值已经处理了回发,也就是说tb的值已经更新了,你直接存取就可以了.
    因为Page_Init()之后就是处理回发的事件,
    你可以在<%@ page %>中加入trace="true",
    这样事件的先后顺序就一目了然。例:(凭记忆手写的,原理应没错吧)
    void Page_Init()
    {
       TextBox tb = new TextBox();
       tb.ID = "tb!";
       tb.Text = "abcd";
    }void Page_Load()
    {
       if(IsPostBack)//你会发现tb.Text是你在浏览器中输入的值。
                     //因为tb.Text的值已经由系统处理好了。
        {
          Response.Write(tb.Text);
        }
        else
        {
        //其他初始化数据。
        }
    }
      

  17.   

    如果楼主还是不明白,建议看看创建数据控件的教程,例如MSDN里的,不过我更推荐Wrox的《ASP.NET服务器控件高级编程》。实际上数据控件(从简单的Repeater到复杂的GridView)都涉及到动态创建控件,数据控件中每一个DataItem相关的控件都是动态创建的,只不过不是在Button_Click首次创建而是在DataBind首次创建,之后都是在Load时候进行“恢复创建”。
      

  18.   

    还有各位,我用的是VS.net2005,可能与VS.net2003有区别,所以我的结果与大家的结果可能有差别。
      

  19.   

    用HIDDEN 对象(<input id="hid_Length" value="0" type="hidden" style="width: 10px" />
    ) 保存 你要的值,后台没什么代码,这些就是动态生成控件的一些JS, 你运行看看!<%@ Page Language="C#" AutoEventWireup="true" CodeFile="WebForm3.aspx.cs" Inherits="test_WebForm3" %><!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>无标题页</title>    <script type="text/javascript">
        var flag=true
        function scrollStart(object,offset)
        {
            object.scrollLeft+=offset;
            if (flag) timeID=window.setTimeout("scrollStart("+object.id+","+offset+")",10);
        }
        function scrollStop()
        {
            flag=false;
            window.clearTimeout(timeID);
            flag=true;
        }
        
        //增加
        function f_Add()
        {
            if(parseInt(document.all("hid_Number").value)<=0)
            {
                document.all("hid_Number").value = 1;
            }
            Layer1.scrollLeft = parseInt(document.all('hid_Length').value)-50;
            var newButton = document.createElement("<input style=\"width:50px\" id='btn"+document.all("hid_Number").value+"' type='button' value='btn"+document.all("hid_Number").value+"' onclick=\"f_SetNuber('"+ document.all("hid_Number").value +"')\" />");
            newTD.appendChild(newButton); 
            document.all("hid_Number").value = parseInt(document.all("hid_Number").value)+1;
            Layer1.scrollLeft += 50;
            document.all('hid_Length').value = parseInt(document.all('hid_Length').value)+50;
        }    //删除
        function f_Delete()
        {
            Layer1.scrollLeft = parseInt(document.all('hid_Length').value)-150;
            document.all("hid_Number").value = parseInt(document.all("hid_Number").value)-1;
            if(document.getElementById("btn"+document.all("hid_Number").value))
            {
                newTD.removeChild(document.getElementById("btn"+document.all("hid_Number").value));
            }
            else
            {
                for ( var i = 50 ; i > 0;i-- )
                {
                    if(document.getElementById("btn"+i))
                    {
                        document.all("btn"+i).focus();
                        newTD.removeChild(document.getElementById("btn"+i));
                        break;
                    }
                }
            }
            document.all('hid_Length').value = parseInt(document.all('hid_Length').value)-50; 
        }    function f_SetNuber(Number)
        {
            document.all("hid_Number").value = parseInt(Number)+1;
        }
        
        </script>    <style type="text/css">body,td,th {
    font-size: 12px;
    }
    </style>
    </head>
    <body>
        <form id="form1" runat="server">
            <table>
                <tr>
                    <td>
                        <input id="btn_Add" onclick="f_Add()" type="button" value="增加" />
                        <input id="btn_Delete" onclick="f_Delete()" type="button" value="删除" /> 
                    </td>
                </tr>
            </table>
            <table width="160" height="24" bgcolor="#FFCC00" border="0" cellpadding="0" cellspacing="0">
                <tr>
                    <td>
                        <b>最新消息</b></td>
                    <td width="20" align="center" valign="middle">
                        <img src="up.gif" alt="向左" width="16" height="16" onmouseout="scrollStop()" onmouseover="scrollStart(Layer1,-1)"
                            style="cursor: hand"></td>
                    <td width="20" align="center" valign="middle">
                        <img src="down.gif" alt="向右" width="16" height="16" onmouseout="scrollStop()" onmouseover="scrollStart(Layer1,1)"
                            style="cursor: hand"></td> <td width="20" align="center" valign="middle">
                    </td>
                </tr>
            </table>
            <table width="160" border="1" cellpadding="0" cellspacing="0" bgcolor="#FFFF99">
                <tr>
                    <td style="height: 25px">
                        <div id="Layer1" style="position: absolute;overflow: hidden; z-index: 1; width: 160px;
                            height: 25px;">
                            <table width="160" border="1" cellpadding="0" cellspacing="0" class="login" style="height: 25px">
                                <tr>
                                    <td id="newTD" valign="top">
                                    </td>
                                </tr>
                            </table>
                        </div>  
                       
                        
                    </td>
                </tr>
            </table> 
            <input id="hid_Number" value="1" type="hidden" style="width: 10px" />
            <input id="hid_Length" value="0" type="hidden" style="width: 10px" />
            <input id="hid_AddIndex" value="0" type="hidden" style="width: 10px" />
            <input id="hid_DeleteIndex" value="0" type="hidden" style="width: 10px" />
        </form>
    </body>
    </html>
      

  20.   

    我用简略的方式写代码给你算了:Page_Load()
    {
      if (!IsPostBack)
      {
        ViewState["IsTextBoxCreated"] = false;
      }
      if ((bool)ViewState["IsTextBoxCreated"])
      {
        CreateTextBox();
      }
    }CreateTextBoxButton_Click()
    {
      if (!(bool)ViewState["IsTextBoxCreated"])
      {
        CreateTextBox();
        ViewState["IsTextBoxCreated"] = true;
      }
    }CreateTextBox()
    {
    //这里是创建一个TextBox并添加到Page.Controls的函数
    //需要为此TextBox的有关属性赋值,特别是ID属性。
    }