c # .net сохранение состояния элемента управления из динамических блоков с помощью мастера управления - PullRequest
2 голосов
/ 11 января 2012

У меня возникают некоторые проблемы при попытке сохранить состояние значений в элементах управления textbox между постбэками в мастере, являющемся частью файла пользовательского элемента управления (.ascx).

Некоторый фон

Это форма заказа для продукта, который может иметь различные параметры (1 продукт может иметь много параметров), поэтому параметры не являются общими.Список опций (извлеченных из базы данных с использованием SubSonic 2) отображается пользователю на этапе запуска мастера для выбранного продукта с использованием синтаксиса «OptionBox-4» (номер на конце является идентификатором).опции в базе данных, чтобы я мог вернуться позже и получить описание.

Затем пользователь может вводить разные количества в каждом из вариантов.

Проблема

Как только пользователь ввел количества в поля и нажал «Далее», значения не сохраняются между обратными передачами или идентификаторами элементов управления.

Код

<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, который, кажется, делает что-то очень похожее на то, чтоМне нужно, чтобы мой.

Еще одно примечание

метод LoadOrderWizard должен быть вызван в событии Page_Load. Это урезанный код только с кодом, относящимся кмоя проблема показана. контрольна самом деле состоит из нескольких различных панелей, которые отображают различную информацию на основе данных, переданных в элемент управления.поэтому наличие кода инициализации в событии Page_Init сработало бы не обязательно.

Ответы [ 2 ]

0 голосов
/ 13 марта 2012

В конце концов, поскольку я не смог найти работоспособного решения для этого, я закончил тем, что использовал переменную сеанса для хранения идентификатора динамического блока и содержащегося в нем значения. Затем я на других страницах проверяю, содержится ли идентификатор текстового поля в сеансе, и восстанавливаю его значение в этом поле.

Поскольку в это поле помещаются только цифры, для меня это решение - обходной путь. Однако было бы неплохо узнать, есть ли другое решение.

0 голосов
/ 13 января 2012

Попробуйте переместить CreateDynamicBoxes () в Page_Init

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