无法加载viewstate - ASP.NET中的动态控件

时间:2013-03-26 15:21:56

标签: asp.net dynamic controls viewstate

我在viewstate上阅读了很多文章,但我无法理解它。

基本上我想要两个带有添加和删除按钮的列表框和一个继续按钮。

当按下Proceed按钮时,隐藏前一个按钮,并为第一个列表框中的每个项目显示一个文本框,其中有2个下拉框用于描述它+第二个列表框中每个项目的文本框(也用于用户添加说明)。

然后我想要一个Finalize Button将所有这些信息保存到数据库中。

到目前为止,我有以下代码:

   <script runat="server">   

    void Page_Load(Object sender, EventArgs e)
    {
        CreateDynamicControls();
        Page.MaintainScrollPositionOnPostBack = true;
        Build2.Visible = false;
        Build3.Visible = false;
        Build4.Visible = false;
        Finish.Visible = false;
    }

    void AddC_Click(Object sender, EventArgs e)
    {
                criteria.Items.Add(addnewc.Text.ToString());
                addnewc.Text = null;
    }

    void RemoveCriterion_Click(Object sender, EventArgs e)
    {
        for (int i = 0; i < criteria.Items.Count; i++)
        {
            if (criteria.Items[i].Selected)
            {
                criteria.Items.Remove(criteria.Items[i]);
                i--;
            }
        }
    }

    void AddAlternative_Click(Object sender, EventArgs e)
    {
                alternatives.Items.Add(addnewa.Text.ToString());
                addnewa.Text = null;
    }

    void RemoveAlternative_Click(Object sender, EventArgs e)
    {
        for (int i = 0; i < alternatives.Items.Count; i++)
        {
            if (alternatives.Items[i].Selected)
            {
                alternatives.Items.Remove(alternatives.Items[i]);
                i--;
            }
        }
    }

    void Continue_Click(Object sender, EventArgs e)
    {
            Build1.Visible = false;
            Build2.Visible = true; 
            Build3.Visible = true;

            CreateDynamicControls();

            Finish.Visible = true;
    }

    void CreateDynamicControls()
    {
        Build2.Controls.Clear();
        Build3.Controls.Clear();

        Build2.Controls.Add(new LiteralControl("<h3>Please define each criterion.</h3><p>By describing it and indicating if it is 1/2 and a/b.</p>"));

        for (int i = 0; i < criteria.Items.Count; i++)
        {
            Build2.Controls.Add(new LiteralControl("<strong>" + criteria.Items[i].Text + "</strong>&nbsp;&nbsp;Description:<br />"));
            TextBox criteriondesc = new TextBox();
            Build2.Controls.Add(criteriondesc);
            criteriondesc.ID = "c" + i.ToString();
            criteriondesc.Rows = 3;
            criteriondesc.Width = 850;
            criteriondesc.TextMode = TextBoxMode.MultiLine;
            Build2.Controls.Add(new LiteralControl("<br />"));

            Build2.Controls.Add(new LiteralControl("Desc1: "));
            DropDownList aim = new DropDownList();
            aim.ID = i.ToString();
            aim.Width = 250;
            aim.Items.Add(new ListItem("1"));
            aim.Items.Add(new ListItem("2"));
            Build2.Controls.Add(aim);

            Build2.Controls.Add(new LiteralControl("&nbsp;&nbsp;&nbsp;&nbsp;Desc2: "));
            DropDownList source = new DropDownList();
            source.ID = i.ToString();
            source.Width = 250;
            source.Items.Add(new ListItem("a"));
            source.Items.Add(new ListItem("b"));
            Build2.Controls.Add(source);

            Build2.Controls.Add(new LiteralControl("<br /><br />"));

        }

        Build3.Controls.Add(new LiteralControl("<h3>Please define each alternative.</h3><p>Please describe each alternaitve in detail.</p>"));

        for (int i = 0; i < alternatives.Items.Count; i++)
        {
            Build3.Controls.Add(new LiteralControl("<strong>" + alternatives.Items[i].Text + "</strong>&nbsp;&nbsp;Description:<br />"));
            TextBox altdesc = new TextBox();
            altdesc.ID = "a" + i.ToString();
            altdesc.Rows = 3;
            altdesc.Width = 850;
            altdesc.TextMode = TextBoxMode.MultiLine;
            Build3.Controls.Add(altdesc);
            Build3.Controls.Add(new LiteralControl("<br />"));
        }

        Build3.Controls.Add(new LiteralControl("<br /><h3>Review dates.</h3><p>Please select a date for a meeting.</p>"));
        OboutInc.Calendar2.Calendar selectdates = new OboutInc.Calendar2.Calendar();
        Build3.Controls.Add(selectdates);
    }

    void Finish_Click(Object sender, EventArgs e)
    {

            Build4.Visible = true;

            foreach (var control in Build2.Controls)
            {
                if (control.GetType() == typeof(TextBox))
                {
                    Build4.Controls.Add(new LiteralControl(((TextBox)control).Text + "<br>"));
                }
            }

            foreach (var control in Build3.Controls)
            {
                if (control.GetType() == typeof(TextBox))
                {
                    Build4.Controls.Add(new LiteralControl(((TextBox)control).Text + "<br>"));
                }
            }

    }
</script>

<asp:Content runat="server" ID="MainContent" ContentPlaceHolderID="MainContent">
    <asp:Panel ID="Build1" runat="server">
    <h3>What is your aim?</h3>
    <p>
        <asp:TextBox ID="goal" runat="server" Width="850px"></asp:TextBox>
    </p>

        <h3>What are the criteria of your decision?</h3>
    <p>
        <asp:ListBox ID="criteria" runat="server" Rows="8" Width="850px"></asp:ListBox><br />
        <asp:Button ID="RemoveCriterion" runat="server" Text="Remove" OnClick="RemoveCriterion_Click" />&nbsp;&nbsp;&nbsp;&nbsp;
        <asp:TextBox ID="addnewc" runat="server" Width="650px"></asp:TextBox>
        <asp:Button ID="AddC" runat="server" Text="Add" OnClick="AddC_Click" />
    </p>

        </p>
        <h3>What are the alternatives of your decision?</h3>

    <p>
        <asp:ListBox ID="alternatives" runat="server" Rows="8" Width="850px"></asp:ListBox><br />
        <asp:Button ID="RemoveAlternative" runat="server" Text="Remove" OnClick="RemoveAlternative_Click" />&nbsp;&nbsp;&nbsp;&nbsp;
        <asp:TextBox ID="addnewa" runat="server" Width="650px"></asp:TextBox>
        <asp:Button ID="AddAlternative" runat="server" Text="Add" OnClick="AddAlternative_Click" />
    </p>
    <p align="right"><asp:Button ID="continue" runat="server" Text="Continue" OnClick="Continue_Click" /></p>


    </asp:Panel>

        <asp:Panel ID="Build2" runat="server">
        </asp:Panel>
            <asp:Panel ID="Build3" runat="server">
        </asp:Panel>
                <asp:Panel ID="Build4" runat="server">
        </asp:Panel>

    <p align="right"><asp:Button ID="Finish" runat="server" Text="Finish" OnClick="Finish_Click" /></p>


</asp:Content>

如您所见,我刚刚尝试从动态创建的文本框字段输出用户的文本。

但是,我收到了错误

  

无法加载视图状态。 viewstate所在的控制树   正在加载必须与用于保存的控制树匹配   在上一个请求期间查看状态。例如,添加时   动态控制,回发期间添加的控件必须匹配   初始期间添加的控件的类型和位置   请求。

at:第169行:Build3.Controls.Add(altdesc);

有谁知道如何使用viewstate修复此问题?

我是ASP.NET新手,我的背景主要是WinForms。

感谢您的帮助和建议!

2 个答案:

答案 0 :(得分:3)

您创建控件的时间太晚了。您应该在页面的Init事件期间创建它们,而不是Page Load。我建议你阅读关于page life cycle

的abit

答案 1 :(得分:2)

我认为最好的办法是:

protected void Page_Load(Object sender, EventArgs e)
{
    if(!IsPostBack)
    {
        CreateDynamicControls();
    }
}
protected override void LoadViewState(object savedState)
{
    base.LoadViewState(savedState);
    CreateDynamicControls();<br/>
}

小样本:

http://class10e.com/Microsoft/which-method-should-you-add-to-the-web-page http://msdn.microsoft.com/en-us/library/ms178472(v=vs.100).aspx