PlaceHolders и постоянные динамические элементы управления (ADVANCED) - PullRequest
0 голосов
/ 22 ноября 2011

Внимание!Эта проблема не для финт сердца.Я потратил несколько дней, пытаясь устранить его.

У меня есть Wizard элемент управления с примерно 5 шагами, каждый из которых имеет несколько элементов управления, от очень простых до очень сложных, таких как пользовательская комбинация jQueryкоробки на основе DropDownList с и TextBox с.Каждый шаг имеет несколько элементов управления, заключенных в элемент управления PlaceHolder.

Wizard вместе со всеми PlaceHolder s и их дочерним элементом Controls вложены в View из MultiView.На той же странице у меня есть еще один View в стиле формы, но не один.Это представление имеет соответствующие PlaceHolder с для каждого из PlaceHolder с на каждом шаге Wizard.

. В зависимости от ReferralUrl, я вызываю следующую функцию, чтобы «переключить» представление из Wizardв представление стиля формы, переместив все элементы управления, а затем установив активное представление следующим образом:

Protected Sub ToggleView() Handles ViewToggle.Click
    If Wizard_mv.ActiveViewIndex = 0 Then
        ViewToggle.Text = "Toggle Wizard View"
        fPH1.Controls.Add(wPH1)
        fPH2.Controls.Add(wPH2)
        fPH3.Controls.Add(wPH3)
        fPH4.Controls.Add(wPH4)
        fPH5.Controls.Add(wPH5)
        Wizard_mv.ActiveViewIndex = 1
    ElseIf Wizard_mv.ActiveViewIndex = 1 Then
        ViewToggle.Text = "Toggle Form View"
        wPH1.Controls.Add(fPH1)
        wPH2.Controls.Add(fPH2)
        wPH3.Controls.Add(fPH3)
        wPH4.Controls.Add(fPH4)
        wPH5.Controls.Add(fPH5)
        Wizard_mv.ActiveViewIndex = 0
    End If
End Sub

Сразу после этого я использую другую функцию для предварительного заполнения элементов управления значениями из записи в базе данных.,После разрешения пользователям вносить некоторые изменения, они могут повторно отправить обновленную запись в базу данных.Проблема в том, что это прекрасно работает, если я делаю это с Wizard, но не после переключения.Трассировка показывает, что Control Tree пуст во время отправки обновленной записи, и, следовательно, я не могу получить введенные пользователем / предварительно заполненные значения из этого представления. Предварительная заливка отлично работает, и все "выбранные" значения верны.Проблема возникает в PostBack после нажатия кнопки отправить, и он теряет все значения и элементы управления.

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

Вот пример моей разметки в моем Wizard (все стили для краткости удалены):

<asp:WizardStep ID="WizardStep1" runat="server" Title="Product Info">
    <asp:PlaceHolder ID="wPH1" runat="server" ViewStateMode="Enabled">
        <asp:Table ID="ProductInfoTable" runat="server" Width="100%">
            <asp:TableHeaderRow>
                <asp:TableHeaderCell><h3>Product Line</h3></asp:TableHeaderCell>
                <asp:TableHeaderCell><h3>Publication Type</h3></asp:TableHeaderCell>
                <asp:TableHeaderCell><h3>Request Type</h3></asp:TableHeaderCell>
            </asp:TableHeaderRow>
            <asp:TableRow>
                <asp:TableCell>
                    <div class="ui-widget">
                        <!-- Autocomplete Combobox -->
                        <asp:DropDownList ID="productLine_ddl" runat="server" DataSourceID="productLineSDS" ViewStateMode="Enabled" DataTextField="Product" DataValueField="ID"></asp:DropDownList>
                        <asp:TextBox ID="productLine_cb" runat="server" EnableViewState="True"></asp:TextBox>
                        <button id="productLine_btn" type="button" title="Show All Items"></button>
                    </div>
                </asp:TableCell>
                <asp:TableCell>
                    <asp:DropDownList ID="docType_ddl" runat="server" DataSourceID="docTypeSDS" DataTextField="DocType" DataValueField="ID"></asp:DropDownList>
                </asp:TableCell>
                <asp:TableCell>
                    <asp:DropDownList ID="requestType_ddl" runat="server" DataSourceID="requestTypeSDS" DataTextField="RequestType" DataValueField="ID"></asp:DropDownList>
                </asp:TableCell>
            </asp:TableRow>
            <asp:TableRow>
                <asp:TableCell ColumnSpan="2">
                    <asp:MultiView ID="Attachment_mv" runat="server" ActiveViewIndex="0">
                        <!-- File Upload/Browsing Display -->
                        <asp:View ID="AttachmentUploadView" runat="server">
                            <h3 class="inlineH">Attach File: </h3>
                            <asp:FileUpload ID="AttachmentFile_btn" runat="server" />
                            <asp:Button ID="UploadFile_btn" runat="server" Text="Upload File" />
                        </asp:View>
                        <!-- File Attached Display -->
                        <asp:View ID="FileAttachedView" runat="server">
                            <h3 class="inlineH">Uploaded File: </h3>
                            <asp:Label ID="FileAttachedLabel" runat="server" Text="Label"></asp:Label>
                            <asp:Literal ID="FilesOnServer" runat="server" />
                        </asp:View>
                    </asp:MultiView>
                </asp:TableCell>
            </asp:TableRow>
        </asp:Table>
    </asp:PlaceHolder>
</asp:WizardStep>

My Page Lifecycle Events, asпросил (в хронологическом порядке для вашего удобства):)

Dim referrerPage As String
'Initialize Dynamic controls here. These are controls that need to be prefilled, etc.
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Init
    'DO NOT PREFILL at this stage, as the Controls are not yet rendered and will cause errors.
    '  Use this section for detecting the "referrerPage" and missing "id" parameters when expected, etc.
    If Not IsPostBack Then
        ViewState.Clear()
    End If

    Try
        referrerPage = Right(Request.UrlReferrer.AbsolutePath, Len(Request.UrlReferrer.AbsolutePath) - Request.UrlReferrer.AbsolutePath.LastIndexOf("/"c) - 1)
    Catch ex As Exception
        If Not String.IsNullOrEmpty(Session.Item("referrerPage")) Then
            referrerPage = Session.Item("referrerPage")
        End If
    End Try

    If StrComp(referrerPage, "wizard.aspx") <> 0 And String.IsNullOrEmpty(Session.Item("referrerPage")) Then 'Initialize Session state to remember "referrerPage"
        Session.Add("referrerPage", referrerPage)
    End If
    If StrComp(referrerPage, "formdetails.aspx") = 0 Then
        If String.IsNullOrEmpty(Request.Params("id")) Then
            'This line checks for an expected "id" param value and if none exists, forwards the page back to "tcom.aspx"
            Response.Redirect(Request.UrlReferrer.AbsolutePath)
        Else
            ToggleView()
        End If
    End If
End Sub

'Prefill Dynamic controls here.
Private Sub Page_PreLoad(sender As Object, e As EventArgs) Handles Me.PreLoad
    If Not IsPostBack Then
        productLine_ddl.DataBind()
        docType_ddl.DataBind()
        requestType_ddl.DataBind()
        '...and several more DataBinds for each individual
        '   control in the wizard. Nothing more.
    End If
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
    If Not IsPostBack Then
        'Benign code for querying the database to get User info for Page.User.Identity.Name
    End If
End Sub

Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRender
    If Not IsPostBack Then
        'Here is completely benign code for hiding a couple controls.
    End If
End Sub

Protected Sub Page_PreRenderComplete(ByVal sender As Object, ByVal e As EventArgs) Handles Me.PreRenderComplete
    'PREFILL HERE when appropriate. This occurs after checking the "referrerPage" and ensuring a value for the "id" parameter.
    If Not IsPostBack Then
        Try
            If Not String.IsNullOrEmpty(Request.Params("id")) Then
                PrefillWizard(Request.Params("id"))
            Else : output.Text += "Source: " + Request.UrlReferrer.AbsolutePath
            End If
        Catch ex As Exception
        End Try
    End If
End Sub

Всем, кто может помочь с этим, вы имеете мою вечную благодарность.;)

1 Ответ

1 голос
/ 23 ноября 2011

Проблема в том, что дерево управления страницей должно быть одинаковым во время каждой обратной передачи.Это означает, что вы должны добавлять все элементы управления каждый раз, когда не имеет значения, которое установлено ActiveViewIndexЖелательно в CreateChildControls или на странице инициализации.В функции ToggleView вы можете установить видимость элементов управления.

...