Ok, below i've pasted working example.
Things to be aware of:
Message=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.
Source=System.Web
ErrorCode=-2147467259
set this property on your dynamic controls
EnableViewState = false
Data for this example looks like this
Brand Engine Color Cost
VW, 1.2, Black, 72 000
VW, 1.2, White, 70 000
VW, 1.6 TDI, Red, 79 500
VW, 1.6 TDI, White, 78 800
Ford, 1.6, Black, 57 600
Ford, 1.6, Green, 57 100
Ford, 2.0 TDCi, Black, 87 300
Ford, 2.0 TDCi, White, 86 600
Basicaly this works like this:
- Choose car brand and select button(button is our criteria for generationg controls)
Ofcourse you can also do logic with drop downs etc.
- On second screen you have one or two drop downs based on your choice
- If you have two drop downs, second is dependant of first drop down's choice, so you have example of dependency and postbacks
Page code:
<form id="form1" runat="server">
<div>
<asp:MultiView ID="mvPanels" runat="server">
<asp:View ID="vPanel1" runat="server">
<table>
<tbody>
<tr>
<td>Pick car</td>
<td><asp:DropDownList ID="ddlBrand" runat="server" /></td>
<td><asp:Button ID="btnPanel1Next" Text="Next" runat="server"
onclick="btnPanel1Next_Click" /></td>
<td><asp:Button ID="btnPanel1NextEngineOnly" Text="Next (pick engine only)" runat="server"
onclick="btnPanel1NextEngineOnly_Click" /></td>
</tr>
</tbody>
</table>
</asp:View>
<asp:View ID="vPanel2" runat="server">
<%--<table>
<tbody>
<tr>
<td>Pick engine</td>
<td><asp:DropDownList ID="ddlEngine" AutoPostBack="true" runat="server"
onselectedindexchanged="ddlEngine_SelectedIndexChanged" /></td>
<td><asp:DropDownList ID="ddlColor" AutoPostBack="true" runat="server"
onselectedindexchanged="ddlColor_SelectedIndexChanged" /></td>
<td><asp:Button ID="btnPanel2Prev" Text="Prev" runat="server"
onclick="btnPanel2Prev_Click" /><asp:Button ID="btnPanel2Next" Text="Next"
runat="server" Enabled="False" onclick="btnPanel2Next_Click" /></td>
</tr>
</tbody>
</table>--%>
</asp:View>
<asp:View ID="vPanel3" runat="server">
<table>
<tbody>
<tr>
<td><asp:Label ID="lblResult" runat="server" /></td>
<td><asp:Button ID="btnPanel3Prev" Text="Prev" runat="server"
onclick="btnPanel3Prev_Click" /><asp:Button ID="btnPanel3Finish"
Text="Confirm" runat="server" onclick="btnPanel3Finish_Click" /></td>
</tr>
</tbody>
</table>
</asp:View>
</asp:MultiView>
</div>
</form>
Code behind:
public partial class Default : System.Web.UI.Page
{
public class CarConfiguration
{
public string Brand { get; set; }
public string Engine { get; set; }
public PaintColor Paint { get; set; }
public string Cost { get; set; }
}
[Serializable]
public class CarConfigurationFilter
{
public string Brand { get; set; }
public string Engine { get; set; }
public PaintColor? Paint { get; set; }
public bool EngineOnly { get; set; }
}
public enum PaintColor
{
Black,
Red,
White,
Green,
}
public List<CarConfiguration> availableCars = new List<CarConfiguration>
{
new CarConfiguration{
Brand = "VW",
Engine = "1.2",
Paint = PaintColor.Black,
Cost = "72 000",
},
new CarConfiguration{
Brand = "VW",
Engine = "1.2",
Paint = PaintColor.White,
Cost = "70 000",
},
new CarConfiguration{
Brand = "VW",
Engine = "1.6 TDI",
Paint = PaintColor.Red,
Cost = "79 500"
},
new CarConfiguration{
Brand = "VW",
Engine = "1.6 TDI",
Paint = PaintColor.White,
Cost = "78 800",
},
new CarConfiguration{
Brand = "Ford",
Engine = "1.6",
Paint = PaintColor.Black,
Cost = "57 600"
},
new CarConfiguration{
Brand = "Ford",
Engine = "1.6",
Paint = PaintColor.Green,
Cost = "57 100"
},
new CarConfiguration{
Brand = "Ford",
Engine = "2.0 TDCi",
Paint = PaintColor.Black,
Cost = "87 300"
},
new CarConfiguration{
Brand = "Ford",
Engine = "2.0 TDCi",
Paint = PaintColor.White,
Cost = "86 600"
},
};
CarConfigurationFilter filter
{
get { return (CarConfigurationFilter)ViewState["Filter"]; }
set { ViewState["Filter"] = value; }
}
//If you have multiview in control you need to create this in event before event PageLoad like LoadViewState, LoadControlState, LoadControlState
protected override void OnPreLoad(EventArgs e)
{
if (IsPostBack && mvPanels.ActiveViewIndex == 1)
{
CreateControlsOnPanel2(true, !filter.EngineOnly);
}
base.OnPreLoad(e);
}
protected override void OnLoad(EventArgs e)
{
if (!IsPostBack)
{
ddlBrand.DataSource = availableCars.Select(x => x.Brand).Distinct();
ddlBrand.DataBind();
filter = new CarConfigurationFilter();
mvPanels.ActiveViewIndex = 0;
}
base.OnLoad(e);
}
protected void btnPanel1Next_Click(object sender, EventArgs e)
{
filter.Brand = ddlBrand.SelectedValue;
filter.EngineOnly = false;
CreateControlsOnPanel2(true, true);
mvPanels.ActiveViewIndex++;
}
protected void btnPanel1NextEngineOnly_Click(object sender, EventArgs e)
{
filter.Brand = ddlBrand.SelectedValue;
filter.EngineOnly = true;
CreateControlsOnPanel2(true, false);
mvPanels.ActiveViewIndex++;
}
void CreateControlsOnPanel2(bool enginePickerEnabled, bool colorPickerEnabled)
{
var btnPanel2Prev = new Button();
btnPanel2Prev.ID = "btnPanel1Prev";
btnPanel2Prev.EnableViewState = false;
btnPanel2Prev.Text = "Prev";
btnPanel2Prev.Click += btnPanel2Prev_Click;
var btnPanel2Next = new Button();
btnPanel2Next.ID="btnPanel2Next";
btnPanel2Next.Text = "Next";
btnPanel2Next.EnableViewState = false;
btnPanel2Next.Enabled = false;
btnPanel2Next.Click += btnPanel2Next_Click;
if (enginePickerEnabled)
{
var ddlEngine = new DropDownList();
ddlEngine.ID = "ddlEngine";
ddlEngine.AutoPostBack = true;
ddlEngine.EnableViewState = false;
var engines = availableCars.Where(x => x.Brand == filter.Brand).Select(found => found.Engine).Distinct().ToList();
engines.Insert(0, String.Empty);
ddlEngine.DataSource = engines;
ddlEngine.DataBind();
if (!String.IsNullOrEmpty(filter.Engine))
{
ddlEngine.SelectedValue = filter.Engine;
if (!colorPickerEnabled)
btnPanel2Next.Enabled = true;
}
else
ddlEngine.SelectedIndex = 0;
ddlEngine.SelectedIndexChanged += ddlEngine_SelectedIndexChanged;
vPanel2.Controls.Add(ddlEngine);
}
//remember to add ID to all dynamic controls or there might be an error on postback
if (colorPickerEnabled)
{
var ddlColor = new DropDownList();
ddlColor.ID = "ddlColor";
ddlColor.AutoPostBack = true;
ddlColor.EnableViewState = false;
ddlColor.SelectedIndexChanged += ddlColor_SelectedIndexChanged;
vPanel2.Controls.Add(ddlColor);
if (!String.IsNullOrEmpty(filter.Engine))
{
var colors = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine).Select(found => found.Paint.ToString()).Distinct().ToList();
colors.Insert(0, String.Empty);
ddlColor.DataSource = colors;
if (filter.Paint.HasValue)
{
ddlColor.SelectedValue = filter.Paint.Value.ToString();
btnPanel2Next.Enabled = true;
}
}
else
{
ddlColor.DataSource = null;
ddlColor.SelectedIndex = 0;
}
ddlColor.DataBind();
}
vPanel2.Controls.Add(btnPanel2Prev);
vPanel2.Controls.Add(btnPanel2Next);
}
protected void ddlEngine_SelectedIndexChanged(object sender, EventArgs e)
{
var ddlEngine = sender as DropDownList;
var btnPanel2Next = (Button)vPanel2.FindControl("btnPanel2Next");
if (!String.IsNullOrEmpty(ddlEngine.SelectedValue))
{
filter.Engine = ddlEngine.SelectedValue;
var colors = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine).Select(found => found.Paint.ToString()).Distinct().ToList();
colors.Insert(0, String.Empty);
filter.Paint = null;
var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor");
if (ddlColor != null)
{
ddlColor.DataSource = colors;
ddlColor.DataBind();
ddlColor.SelectedIndex = 0;
btnPanel2Next.Enabled = false;
}
else
btnPanel2Next.Enabled = true;
}
else
{
var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor");
if (ddlColor != null)
{
ddlColor.Items.Clear();
ddlColor.SelectedIndex = -1;
}
filter.Engine = null;
btnPanel2Next.Enabled = false;
}
}
protected void ddlColor_SelectedIndexChanged(object sender, EventArgs e)
{
var ddlColor = (DropDownList)vPanel2.FindControl("ddlColor");
var btnPanel2Next = (Button)vPanel2.FindControl("btnPanel2Next");
if (!String.IsNullOrEmpty(ddlColor.SelectedValue))
{
filter.Paint = (PaintColor)Enum.Parse(typeof(PaintColor), ddlColor.SelectedValue);
btnPanel2Next.Enabled = true;
}
else
{
filter.Paint = null;
btnPanel2Next.Enabled = false;
}
}
protected void btnPanel2Prev_Click(object sender, EventArgs e)
{
filter.Engine = null;
filter.Paint = null;
mvPanels.ActiveViewIndex--;
}
protected void btnPanel2Next_Click(object sender, EventArgs e)
{
mvPanels.ActiveViewIndex++;
var selectedConfiguration = availableCars.Where(x => x.Brand == filter.Brand && x.Engine == filter.Engine
&& (!filter.Paint.HasValue || x.Paint == filter.Paint)).Distinct().FirstOrDefault();
if (selectedConfiguration != null)
lblResult.Text = String.Format("You have selected {0} {1} {2} for {3} PLN", selectedConfiguration.Brand,
selectedConfiguration.Engine, selectedConfiguration.Paint, selectedConfiguration.Cost);
}
protected void btnPanel3Prev_Click(object sender, EventArgs e)
{
mvPanels.ActiveViewIndex--;
CreateControlsOnPanel2(true, !filter.EngineOnly);
}
protected void btnPanel3Finish_Click(object sender, EventArgs e)
{
}
}
If you have any additional questions I will be glad to help