Поддерживать состояние свертывания при обратной передаче ASP.NET

#c# #asp.net #bootstrap-4 #webforms

#c# #asp.net #bootstrap-4 #веб-формы

Вопрос:

У меня есть две разные формы, которые сворачиваются и показывают либо одну, либо другую, и есть кнопка для управления ими.

 <div>
    <button type="button" 
            data-toggle="collapse" 
            data-target=".multi-collapse" 
            aria-expanded="false" 
            aria-controls="form1 form2"> Change Form
    </button>

    <div class="collapse multi-collapse show" id="form1">
        <asp:DropDownList AutoPostBack="true" 
                          OnSelectedIndexChanged="SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1" 
                          ID="Ddl1" 
                          runat="server">
        </asp:DropDownList>
        <asp:DropDownList ID="Ddl2" 
                          runat="server">
        </asp:DropDownList>
        <asp:Button ID="Button1" OnClick="SubmitBtn"
    <div>

    <div class="collapse multi-collapse" id="form2">
        <asp:DropDownList AutoPostBack="true" 
                          OnSelectedIndexChanged="SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1" 
                          ID="Ddl1" 
                          runat="server">
        </asp:DropDownList>
        <asp:DropDownList ID="Ddl2" 
                          runat="server">
        </asp:DropDownList>
        <asp:Button ID="Button1" OnClick="SubmitBtn"
    <div>
</div>

  

Моя проблема в том, что всякий раз, когда появляется сообщение, я теряю состояние свертывания форм, и оно возвращается к отображению form1 и скрытию form2.

Я хочу сохранить состояние сворачиваемых файлов, чтобы они оставались неизменными после обратной передачи, и я не знаю, как это сделать.

Комментарии:

1. Используйте файлы cookie или сохраняйте состояние в скрытом поле и применяйте после обратной передачи.

2. Или сохранить состояние в URL в качестве параметра запроса. Вот список от Microsoft: learn.microsoft.com/en-us/aspnet/core/fundamentals /…

Ответ №1:

Я сделал это через PageRequestManager, конечно, сохраняя состояние одного или двух разделов, в вашем случае их два, но если их больше, решение, которое я даю, довольно сложное, но функциональное:

ASPX-код:

Добавьте свои элементы управления в UpdatePanel

 <div>
    <button type="button" 
            data-toggle="collapse" 
            data-target=".multi-collapse" 
            aria-expanded="false" 
            aria-controls="form1 form2"> Change Form
    </button>

    <asp:UpdatePanel ID="up" runat="server">
        <ContentTemplate>
        
            <div class="collapse multi-collapse show" id="form1">
                <asp:DropDownList AutoPostBack="true" 
                                  OnSelectedIndexChanged="Ddl1_SelectedIndexChanged"
                                  ID="Ddl1" 
                                  runat="server">
                </asp:DropDownList>
                <asp:DropDownList ID="Ddl2" 
                                  runat="server">
                </asp:DropDownList>
                <asp:Button runat="server" ID="Button1" OnClick="Button1_Click" Text="btn1" />
            </div>

            <div class="collapse multi-collapse" id="form2">
                <asp:DropDownList AutoPostBack="true" 
                                  OnSelectedIndexChanged="DropDownList1_SelectedIndexChanged"
                                  ID="DropDownList1" 
                                  runat="server">
                </asp:DropDownList>
                <asp:DropDownList ID="DropDownList2" 
                                  runat="server">
                </asp:DropDownList>
                <asp:Button runat="server" ID="Button2" OnClick="Button1_Click1" Text="btn2" />
            </div>

        </ContentTemplate>
    </asp:UpdatePanel>
</div>
  

Код JavaScript:

Событие add_beginRequest — это событие, которое запускается при запуске обратной передачи, и можно сохранить состояние DOM, в то время как add_endRequest — это событие, которое запускается при обновлении панели и завершении обратной передачи, здесь элементы управления расположены в соответствии с условиями:

 <script type="text/javascript">

    var statusForm1 = false,
        statusForm2 = false;

    var prm = Sys.WebForms.PageRequestManager.getInstance();

    function EndRequestHandler(sender, args) {

        if (statusForm1) {
            $('#form1').collapse('show');
        }
        if (statusForm2) {
            $('#form2').collapse('show');
        }

    }

    function BeginRequestHandler(sender, args) {

        statusForm1 = $('#form1').is(":visible");
        statusForm2 = $('#form2').is(":visible");

    }

    prm.add_beginRequest(BeginRequestHandler);
    prm.add_endRequest(EndRequestHandler);

</script>
  

Комментарии:

1. Спасибо! Очень хорошее объяснение и легко читаемый код.

Ответ №2:

Существует простой и прямой способ сделать это, добавив класс show к div тому, который вы хотите на самом деле показать. Итак, чтобы сделать это, вы должны установить оба div s для запуска на сервере. Вот моя предложенная идея для этой проблемы:

 <div class="collapse multi-collapse show" id="myform1" runat="server"> 
    <!-- because in aspx, there is already a form1 form which is parent of all elements that runs at server -->
    <!-- Other elements go here -->
</div>

<div class="collapse multi-collapse" id="myform2" runat="server">
    <!-- Other elements go here -->
</div>
  

И в событиях сервера вам нужно скрыть и показать соответствующие divs , добавив к ним классы.

 protected void SubmitBtn1(object sender, EventArgs e)
{
    // DoStuff(); 
    ShowMyForm1();

}
protected void SubmitBtn2(object sender, EventArgs e)
{
    // DoStuff(); 
    ShowMyForm2();

}

protected void SetDdl2ValuesBasedOnWhatIsSelectedOnDdl1(object sender, EventArgs e)
{
    // DoStuff();
    // I assume this dropdown is in second form div.
    ShowMyForm2();

}
private void ShowMyForm1()
{
    myform1.Attributes["class"] = "collapse multi-collapse show"; // this will show the div
    myform2.Attributes["class"] = "collapse multi-collapse"; // this will hide the div.
}
private void ShowMyForm2()
{
    myform1.Attributes["class"] = "collapse multi-collapse"; // this will hide the div
    myform2.Attributes["class"] = "collapse multi-collapse show"; // this will show the div
}
  

Обратите внимание, я дал два события для вашей кнопки отправки, потому что она появлялась в обеих формах и имела одинаковое ID значение для нее, что недопустимо для серверных элементов управления. An ID должен быть уникальным. И у вас form2 есть все элементы, дублированные в нем из form1

Итак, чтобы различать эти элементы, вам нужно будет указать им разные ID s.