Reputation: 57
I have read many articles on viewstate but I can't get my head around it.
Basically I want to have two listboxes with add and remove buttons and a Proceed button.
When the Proceed button is pressed, the previous is hidden and a textbox is presented for each item in the first list box with 2 drop down boxes to describe it + a textbox for each item in the second list box (also for the user to add a description).
I then want a Finalise Button to save all this information to a database.
So far I have the following code:
<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> 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(" 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> 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" />
<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" />
<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>
As you can see, at the minute I am just trying to output the user's text from the dynamically created textbox fields.
However, I am getting the error
Failed to load viewstate. The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request. For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request.
at: Line 169: Build3.Controls.Add(altdesc);
Does anyone know how to fix this problem with the viewstate?
I am very new to ASP.NET, my background is mainly in WinForms.
Thank you for any help and advice!!
Upvotes: 3
Views: 9962
Reputation: 3185
I think the best way to do it, it would be :
protected void Page_Load(Object sender, EventArgs e)
{
if(!IsPostBack)
{
CreateDynamicControls();
}
}
protected override void LoadViewState(object savedState)
{
base.LoadViewState(savedState);
CreateDynamicControls();<br/>
}
Small sample:
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
Upvotes: 2
Reputation: 2123
You are creating your controls too late. You should create them during the Init events of the page, and not Page Load. I suggest You read abit about page life cycle
Upvotes: 3