c#.net 使用向导控件从动态框保持控件状态

标签 c# asp.net user-controls viewstate wizard

我在尝试在属于用户控件 (.ascx) 文件的向导中的回发之间保持文本框控件中值的状态时遇到一些问题。

一些背景

这是一个可以有不同选项的产品的订单(1 个产品可以有多个选项),因此选项不是通用的。 在所选产品向导的“开始”阶段,使用语法“OptionBox-4”(末尾的数字是 ID)向用户显示选项列表(使用 SubSonic 2 从数据库中提取)数据库中的选项,这样我可以稍后返回并获取描述。

然后用户可以在每个选项中输入不同的数量。

问题

一旦用户在框中输入了数量并点击“下一步”,值就不会在回发之间存储,也不会存储控件的 ID。

代码

<asp:Wizard ID="Wizard1" runat="server" ActiveStepIndex="0"
    DisplaySideBar="False" onnextbuttonclick="Wizard1_NextButtonClick" 
    onpreviousbuttonclick="Wizard1_PreviousButtonClick" 
    FinishCompleteButtonText="Submit request"  
    onfinishbuttonclick="Wizard1_FinishButtonClick" 
    onactivestepchanged="Wizard1_ActiveStepChanged" 
    onprerender="Wizard1_PreRender" >
    <FinishPreviousButtonStyle CssClass="subbutton" />
    <FinishCompleteButtonStyle CssClass="subbutton" />
    <StartNextButtonStyle CssClass="subbutton" />
    <StepNextButtonStyle CssClass="subbutton" />
    <StepPreviousButtonStyle CssClass="subbutton" />
    <WizardSteps>
        <asp:WizardStep runat="server" StepType="Start" title="Description" ID="vgStep1">
            <fieldset class="emailform">
            <ul runat="server" id="optionList">
                <asp:PlaceHolder id="DynamicBoxes" runat="server" />
            </ul>
            </fieldset>
        </asp:WizardStep>
        <asp:WizardStep ID="WizardStep1" runat="server" Title="Your details" StepType="Finish">
            <h3>Order summary</h3>
            <asp:Literal ID="ltlSummary" runat="server"></asp:Literal>
        </asp:WizardStep>
        <asp:WizardStep ID="WizardStep2" runat="server" StepType="Complete" Title="Thank you">

        </asp:WizardStep>
    </WizardSteps>
</asp:Wizard>

相关代码隐藏

    class ResponseCollection : List<string> { }
private int? NrOfOptions
{
    get { return (int?)ViewState["NrOfOptions"]; }
    set { ViewState["NrOfOptions"] = value; }
}
public PartnerProductOrderableOptionCollection colOptions;
public PartnerProductOrderable prodOrderable;

protected void Page_Load(object sender, EventArgs e)
{
    LoadOrderWizard(Utility.GetPartnerProductId(Request.QueryString["ppid"]));
    CreateDynamicBoxes();
}

#region Ordering wizard
private void LoadOrderWizard(int p)
{

    partnerProduct = new PartnerProduct(p);

    prodOrderable = new PartnerProductOrderable("PartnerProductId", p);

    colOptions = new PartnerProductOrderableOptionCollection();
    colOptions.LoadAndCloseReader(PartnerProductOrderableOption.FetchByParameter("OrderableId", prodOrderable.OrderableId, OrderBy.Asc("ListOrder")));
    if (!IsPostBack)
    {
        this.NrOfOptions = colOptions.Count;
    }
}

protected void Wizard1_ActiveStepChanged(object sender, EventArgs e)
{
    if (Wizard1.ActiveStepIndex == 1)
    {
        ResponseCollection responses = CollectValuesFromDynamicBoxes();
        ltlSummary.Text += "Controls:";
        foreach (Control c in DynamicBoxes.Controls)
        {
            ltlSummary.Text += c.ID + ",";
            if (c is TextBox)
            {
                ltlSummary.Text += ((TextBox)c).ID + ",";
                if (!String.IsNullOrEmpty(((TextBox)c).Text))
                {
                    int optionid = int.Parse(c.ID.Split('-')[1]);
                    PartnerProductOrderableOption o = new PartnerProductOrderableOption(optionid);
                    ltlSummary.Text += "<strong>Quantity: </strong>" + ((TextBox)c).Text + "<br />";
                    ltlSummary.Text += "<strong>Description: </strong>" + o.Description + " - " + o.Price + "<hr />";

                }
            }
        }
    }
}

protected void Wizard1_PreviousButtonClick(object sender, WizardNavigationEventArgs e)
{
}

protected void Wizard1_FinishButtonClick(object sender, WizardNavigationEventArgs e)
{
    ResponseCollection responses = CollectValuesFromDynamicBoxes();
}
protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
    if (e.CurrentStepIndex == 0)
    {
        int newNumberOfOptions = colOptions.Count;
        int? oldNumberOfOptions = this.NrOfOptions;


        if (!oldNumberOfOptions.HasValue || newNumberOfOptions != oldNumberOfOptions.Value)
        {
            this.NrOfOptions = newNumberOfOptions;

            CreateDynamicBoxes();
        }
    }
}
private void CreateDynamicBoxes()
{
    if (!this.NrOfOptions.HasValue)
        return;

    DynamicBoxes.Controls.Clear();

    foreach (PartnerProductOrderableOption opt in colOptions)
    {
        HtmlGenericControl li = new HtmlGenericControl("li");
        DynamicBoxes.Controls.Add(li);

        TextBox box = new TextBox();
        box.ID = "OptionBox-" + opt.OptionId;
        box.Width = 40;
        box.MaxLength = 6;

        li.Controls.Add(box);

        Label lblOpt = new Label();
        lblOpt.ID = "lblOption-" + opt.OptionId;
        lblOpt.Text = opt.Description + " - " + opt.Price;
        li.Controls.Add(lblOpt);
    }
    this.NrOfOptions= colOptions.Count;
}

private ResponseCollection CollectValuesFromDynamicBoxes()
{
    ResponseCollection responses = new ResponseCollection();
    for (int i = 0; i < this.NrOfOptions.Value; i++)
    {
        TextBox box = (TextBox)DynamicBoxes.FindControl("OptionBox-" + i);
        string response = box.Text.Trim();

        if (response.Length > 0)
            responses.Add(response);
    }
    return responses;
}


protected void Wizard1_PreRender(object sender, EventArgs e)
{

}

protected override void OnLoad(EventArgs e)
{
    base.OnLoad(e);

}

#endregion

代码松散地基于 http://aspnetresources.com/blog/dynamic_text_bBoxes_in_wizard_control这似乎与我需要我做的事情非常相似。

另一个笔记

必须在 Page_Load 事件中调用 LoadOrderWizard 方法。这是一个精简的代码,只显示了与我的问题相关的代码。该控件实际上由几个不同的面板组成,这些面板根据传递给控件的数据显示不同的信息。因此在 Page_Init 事件中包含初始化代码会不必要地触发。

最佳答案

尝试将 CreateDynamicBoxes() 移动到 Page_Init

protected void Page_Init(object sender, EventArgs e)
{
    CreateDynamicBoxes();
}

关于c#.net 使用向导控件从动态框保持控件状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8818271/

相关文章:

c# - Linq to SQL 可空整数?

c# - Linq-to-SQL 3 表,获取结果为 List<string>

asp.net - Web 部署任务失败

asp.net - 如何向中继器内的用户控件提供 'data'?

c# - 基于组件的架构 : Replacing an assembly at runtime

c# - LabView 应用程序中引用的 C# .dll 是否可以访问 app.config 文件?

c# - 如何从我的 App_Themes 文件夹中列出可用的 Css 类?

wpf - 为用户控件设置样式

asp.net - 在 asp.net 中显示用户消息的好方法的建议?

c# - 使用 css 从母版页覆盖导航