【问题标题】:Failed to load viewstate - dynamic controls in ASP.NET无法加载视图状态 - ASP.NET 中的动态控件
【发布时间】:2013-03-26 15:21:56
【问题描述】:

我已经阅读了很多关于 viewstate 的文章,但我无法理解它。

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

按下“继续”按钮时,前一个被隐藏,第一个列表框中的每个项目都会显示一个文本框,其中有 2 个下拉框来描述它+第二个列表框中的每个项目都有一个文本框(也适用于用户添加描述)。

然后我想要一个完成按钮来将所有这些信息保存到数据库中。

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

   <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>

如您所见,此刻我只是试图从动态创建的文本框字段中输出用户的文本。

但是,我得到了错误

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

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

有谁知道如何用视图状态解决这个问题?

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

感谢您的任何帮助和建议!

【问题讨论】:

  • 这对控制丢失有帮助吗?
  • 是的,因为它会阻止您遇到此类问题。这些控件将自动(重新)创建动态控件。您可以使用模板字段,然后您就可以使用任何控件。

标签: asp.net dynamic controls viewstate


【解决方案1】:

您创建控件为时已晚。您应该在页面的 Init 事件期间创建它们,而不是在页面加载期间创建它们。我建议你阅读一下page life cycle

【讨论】:

  • 我试过了,没有抛出任何错误,但文本框中的文本没有输出。我假设当时没有创建控件?
  • 如果您在页面上看到文本框,则它们已创建。你指的是哪个文字?用户输入的东西?因为我没有看到你绑定任何东西
  • 是的对不起,测试它我在文本框中输入了一些数据,这没有显示在第三个屏幕上(因为它应该来自 Finish_Click)
  • 我不认为它与视图状态有关,也许 ids 的某些东西搞砸了,因为你动态分配它们?您需要调试才能看到您正在重新创建相同的控制树...
  • 我将 CreateDynamicControls() 添加到 Page_Init 并且它确实触发了。但由于某种原因,Build2 中只有一个控件是 LiteralControl(一些文本)。知道这是为什么吗? :(
【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多