我有一个位于多视图控件内的网站表单(c#)。 muliview控件有4个步骤,因此前3个步骤收集信息,如果有效则移动到按钮单击的下一个视图。
我想根据之前的答案动态构建表单,但是从我到目前为止所读到的内容来看,我有点不确定如何实现这一点。
例如,在第1步,用户完成一些文本框控件并单击“提交”。
根据面板1中提交的数据,下一个面板需要动态创建一些控件 - 一些标签,一些文本框。
由于此次点击是在init和page_load之后,我不确定这是如何工作的。
当然,我可以预先创建所有标签/文本框控件并根据需要禁用它们,但这似乎是对资源的一种很差的使用。
总而言之,我对使用动态控件缺乏经验,所以任何建议都会受到赞赏。
答案 0 :(得分:1)
好的,下面我贴了工作示例。 需要注意的事项:
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
在动态控件上设置此属性
EnableViewState = false
此示例的数据如下所示
品牌引擎颜色成本
大众,1.2,黑色,72 000
大众,1.2,白色,70 000
大众,1.6 TDI,红色,79 500
大众,1.6 TDI,白色,78 800
福特,1.6,黑色,57 600
福特,1.6,绿色,57 100
福特,2.0 TDCi,黑色,87 300
福特,2.0 TDCi,白色,86 600
Basicaly的工作原理如下:
网页代码:
<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>
代码背后:
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)
{
}
}
如果您有任何其他问题,我将很乐意为您提供帮助