Как перезагрузить динамически добавленные пользовательские элементы управления после нажатия кнопки Добавить

#c# #asp.net #.net #custom-controls #webusercontrol

#c# #asp.net #.net #пользовательские элементы управления #webusercontrol

Вопрос:

У меня есть требование, при котором я должен динамически загружать пользовательский элемент управления при нажатии кнопки Добавления, которая присутствует на родительской странице. Пользовательский элемент управления содержит текстовые поля, выпадающие списки и кнопку удалить. Если я нажму кнопку Удаления конкретного пользовательского элемента управления, он будет удален. С этим все работает нормально. Проблема в том, что при нажатии кнопки Добавить запись страницы возвращается, и выбранные значения в пользовательском элементе управления теряют свои значения. Мне нужен способ получить все динамически добавляемые элементы управления из кода и сохранить его в состоянии просмотра, а при загрузке страницы снова преобразовать его в пользовательский элемент управления и добавить его на страницу. Пожалуйста, помогите с этим.

SecondaryDestination.ascx будет выглядеть так: держатель места будет динамически загружать элементы управления.

 <td><asp:Label id="lblSecondary">Secondary Destination</asp:Label></td>     
<td>asp:DropDownList id="ddlSecondary" runat="server" CssClass="ddlbox" AutoPostBack="true"></asp:DropDownList> </td>   
<asp:UpdatePanel ID="updateEmailFtp" runat="server" UpdateMode="Conditional">
<ContentTemplate>
    <asp:PlaceHolder ID="plcEmail" runat="server">
        <table cellpadding="0" cellspacing="0" border="0" class="tbl_form" runat="server" id="tblSecondary">
        </table>    
    </asp:PlaceHolder>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="ddlSecondary" EventName="SelectedIndexChanged" />
</Triggers>
 

Пользовательские элементы управления добавляют элементы управления динамически

 protected void ddlSecondary_SelectedIndexChanged(object sender, EventArgs e)
    {
        if(ddlSecondary.SelectedIndex > 0)
        {
            pickerSecondaryViewPresenter = new PickerSecondaryViewPresenter(this);
            DestinationBO secondaryDestination = pickerSecondaryViewPresenter.getSecondaryDestination(int.Parse(ddlSecondary.SelectedItem.Value));

            if(secondaryDestination.DestinationType == "Email")
            {
                HtmlTable tblContent = (HtmlTable)FindControl("tblSecondary");

                Label lblPrimary = new Label();                 
                lblPrimary.Text = "Email Disstribution List";                                       
                HtmlTableCell tcPrimary1 = new HtmlTableCell();
                tcPrimary1.Controls.Add(lblPrimary);

                Label lblPrimaryDistributionList = new Label(); 
                lblPrimaryDistributionList.Text = secondaryDestination.DistributionList;
                HtmlTableCell tcPrimary2 = new HtmlTableCell();
                tcPrimary2.Controls.Add(lblPrimaryDistributionList);

                HtmlTableRow trPrimary = new HtmlTableRow();
                trPrimary.Controls.Add(tcPrimary1);
                trPrimary.Controls.Add (tcPrimary2);                        
                tblContent.Controls.Add(trPrimary);                     
            }
            else
            {
                Label lblFtp = new Label();                 
                lblFtp.Text = "Ftp Host";
                HtmlTableCell tcPrimary1 = new HtmlTableCell();
                tcPrimary1.Controls.Add(lblFtp);

                Label lblFtpHost = new Label();                 
                lblFtpHost.Text = secondaryDestination.FtpHost;                 
                HtmlTableCell tcPrimary2 = new HtmlTableCell();
                tcPrimary2.Controls.Add(lblFtpHost);    

                Button btn = new Button();
                btn.Text = "Connect FTP";
                tcPrimary2.Controls.Add(btn);   

                HtmlTableRow trPrimary1 = new HtmlTableRow();
                trPrimary1.Controls.Add(tcPrimary1);
                trPrimary1.Controls.Add (tcPrimary2);   

                Label lblDirectory = new Label();                   
                lblDirectory.Text = "Ftp Directory";
                HtmlTableCell tcPrimary3 = new HtmlTableCell();
                tcPrimary3.Controls.Add(lblDirectory);

                TextBox txtDirectory = new TextBox();                   
                txtDirectory.Text = "";                 
                HtmlTableCell tcPrimary4 = new HtmlTableCell();
                tcPrimary4.Controls.Add(txtDirectory);

                HtmlTableRow trPrimary2 = new HtmlTableRow();
                trPrimary2.Controls.Add(tcPrimary3);
                trPrimary2.Controls.Add(tcPrimary4);

                tblSecondary.Controls.Add(trPrimary1);      
                tblSecondary.Controls.Add(trPrimary2);

            }
 

Этот пользовательский элемент управления будет добавлен в page1.aspx:

 <div>
<asp:UpdatePanel id ="up1" UpdateMode="conditional">
    <ContentTemplate>
        <uc:DestinationPicker id="destinatioPicker" runat="server" ></uc:DestinationPicker>
    </ContentTemplate>
</asp:UpdatePanel>
</div>
<asp:PlaceHolder ID="divSecondary" runat="server">  
    <ucS:DestinationPickerSecondary id="destinationPickerSecondary" runat="server" ></ucS:DestinationPickerSecondary>       
</asp:PlaceHolder>  

<div>
    <asp:Button id="btnAddSecondary" Text="Add Secondary" runat="server" OnClick="btnAddSecondary_Click"></asp:Button>
</div>

</div>
 

Добавление и удаление пользовательских элементов управления работает нормально:

 protected void Page_Load(object sender, EventArgs e)
{    if(IsPostBack)
{
    AddAndRemoveDynamicControls();
}
}
 

Моя проблема в том, что мне нужно сохранять выбранные элементы в раскрывающемся списке ранее добавленного пользовательского элемента управления при каждом нажатии кнопки Добавить, чтобы добавить новый экземпляр пользовательского элемента управления, добавляемый динамически

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

1. вместо добавления элементов управления из кода, почему бы не изменить свойство display CSS следующим образом display:none;

2. Я не могу использовать css, поскольку количество добавляемых пользовательских элементов управления неизвестно в начале. При нажатии кнопки добавления мне нужно добавить n количество пользовательских элементов управления.

3. @ Sid: я мог бы опубликовать изображения для лучшего понимания моего квеста. Но у меня пока недостаточно репутации, чтобы сделать это.

Ответ №1:

Когда viewstate загружается во время обратной обработки, он связывает значения в состояниях представления с загруженными элементами управления. Вы должны динамически перезагружать элемент управления перед обработкой viewstate. Я делал это в прошлом во время события page_init .

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

1. Да, мне нужно сделать то же самое. Но мне нужно, чтобы значения элементов управления внутри пользовательского элемента управления также были восстановлены. ПОЭТОМУ мне нужно сохранить эти значения в состоянии сеанса или просмотра, чтобы я мог снова их привязать. Мне нужен wway для доступа к этому в защищенном void btnAddSecondary_Click(отправитель объекта, EventArgs e) { }

2. Значения сохраняются в viewstate. Проблема в том, что динамически добавляемые пользовательские элементы управления не существуют во время обратной передачи. Они должны динамически добавляться во время каждой обратной отправки, чтобы быть сохраненными. Однако обычно происходит то, что вы загружаете их после загрузки ViewState, и элементам управления присваиваются значения. Вам нужно будет снова динамически добавлять элемент управления в Page_Init, чтобы значения были присвоены элементу управления при загрузке viewstate.

3. Спасибо за руководство @user3754182. Не могли бы вы, пожалуйста, помочь мне с примером кода. В основном в AddAndRemoveDynamicControls() я добавляю пользовательские элементы управления следующим образом: Control c = GetPostBackControl(страница);

4. Вам нужно будет переместить AddAndRemoveDynamicControls() в Page_Init() . Вам просто нужно добавить динамические элементы управления перед обработкой состояния представления. Дело не в том, чтобы делать что-то правильно, а в том, чтобы делать что-то в нужное время.