FormView su una pagina master non può vedere databound controlli attraverso ContentPlaceHolder confine

StackOverflow https://stackoverflow.com/questions/791572

  •  16-09-2019
  •  | 
  •  

Domanda

Ho un certo numero di FormViews di analoga struttura. Nel tentativo di evitare la marcatura duplicato, ho creato una pagina master che contiene il FormView, e messo un ContentPlaceHolder all'interno del FormView. Gli specifici controlli databound - che sono l'unica cosa che cambia da una pagina all'altra - sono quindi nella pagina che utilizza tale pagina master

.

Così ho una pagina master che sembra qualcosa di simile:

<%@ master ... %>
...
<form runat=server>
...
   <asp:formview runat="server" ... >
      <edititemtemplate>
         ... Lots of common markup ...
         <asp:contentplaceholder id='FormRows' runat='server' />
         ... Lots more common markup ...
       </edititemtemplate>
    </asp:formview>
...
</form>

e una pagina utilizzando tale pagina master che sembra qualcosa di simile:

<%@ page masterpagefile="Form.Master" ... %>
<asp:content contentplaceholderid="FormRows" runat="server" >
   ...
   <p>
     Field One: 
     <asp:textbox runat=server text='<%#Bind("Field1")%>' id='Field1' />
   </p>
   <p>
     Field Two: 
     <asp:textbox runat=server text='<%#Bind("Field2")%>' id='Field2' />
   </p>
   ...
</asp:content>

Con un record esistente, il FormView vede attraverso ai controlli databound (Field1, ecc) e li popola con i dati corretti. Ma durante l'inserimento o l'aggiornamento, non li vede, e non sono inclusi nel inserimento o aggiornamento. Nel caso FormView_ItemInserting, e.Values è vuota; anche in caso FormView_ItemUpdating, e.NewValues è vuoto.

  1. C'è un modo per provocare il FormView sulla pagina master per vedere attraverso i controlli databound all'interno del ContentPlaceHolder?

  2. In mancanza di questo, c'è un modo semplice per identificare i controlli che sono databound con <%#Bind(...)%> modo che posso aggiungere manualmente alla borsa valori?

È stato utile?

Soluzione

Credo che questo si rivelerà difficile, se non è possibile; in realtà io sono sorpreso che l'associazione dati funziona a tutti!

Si consiglia di provare un diverso metodo di incapsulare il vostro controllo FormView.

Si potrebbe provare a posizionare il controllo FormView in un controllo ascx con un segnaposto dove ora avete la ContentPlaceHolder.

Quindi in ogni pagina ASPX, si potrebbe avere una pagina ASCX specchio che contiene il filler per il segnaposto. Si potrebbe dare loro gli stessi nomi (Page1.aspx utilizza Page1.ascx) o impostare una convenzione di denominazione come Pagina1-Content.ascx, in modo che l'ascx FormView sarebbe capire che cosa è il controllo di riempimento è chiamato, utilizzare Page.LoadControl () caricare il controllo per percorso, e collegare tale contenuto nella fase di inizializzazione.

Ora, i controlli di contenuti hanno il vantaggio di essere in grado di avere proprietà pubbliche, così si potrebbe associare a tali proprietà pubblica, e hanno le proprietà navetta dati da e verso i controlli server appropriate nel riempimento ascx file.

Purtroppo è il doppio dei file (a causa della ASPX e ASCX richiesto per ogni pagina), ma piuttosto lavorare-unintensive rispetto all'alternativa (duplicare tutto ciò che il codice)

Naturalmente, non si è ci ha detto che tutto il tuo markup comune è, ma il vostro codice comune potrebbe andare in un CommonMarkupHeader.ascx e CommonMarkupFooter.ascx come bene e incluso FormView unica di ogni pagina.

Altri suggerimenti

Ci sono un paio di cose che vengono in mente il motivo per cui questa configurazione non funzionerà e può portare a più codice di markup.

Se si dispone di un DataSource definito nella pagina master non gestirà i diversi dati associati controlli da ogni pagina, senza l'aggiunta più logica alla pagina master per modificare la query ecc

Tutte le viste modulo vengono accoppiati insieme aumentando la complessità dei cambiamenti lungo la strada

Vorrei andare con pagine separate per ogni FormView ridurre la complessità del codice, debugging e la capacità di cambiare

Solo i miei due centesimi

Dove hai tag form server? Può essere in segnaposto di contenuto, invece di pagina master, quindi i valori non inviare alla pagina server dopo Invia

Potreste essere in grado di fare qualcosa di simile ...

Definisci un'interfaccia per le "pagine di dati" che ha una firma metodo che restituisce una fonte di dati associabile ..

public interface IFormViewChild {
   IEnumerable GetFormData();
}

Quindi è possibile avere le "pagine di dati" implementare l'interfaccia ...

public class ChildDataPage : Page, IDataPage {
   public IEnumerable GetFormData() {
      // code to return stuff here
   }
}

Infine, in carico del vostro masterpage () evento ...

if (Page is IFormViewChild) {
   myFormViewControl.DataSource = ((IFormViewChild)Page).GetFormData();
   myFormViewControl.DataBind();
}

Si prega di tenere presente che questo è tutto il codice psudo digitato direttamente in questo editor di modulo web .. quindi è probabilmente sbagliato. Ma potrebbe non essere:)

Ecco una soluzione provvisoria - non elegante, ma funziona. Nel code-behind per Form.Master ho qualcosa in queste righe:

    Private Sub FormView1_ItemInserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewInsertEventArgs) Handles FormView1.ItemInserting
        ManuallyAddValues(e.Values)
    End Sub

    Private Sub FormView1_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.FormViewUpdateEventArgs) Handles FormView1.ItemUpdating
        ManuallyAddValues(e.NewValues)
    End Sub

    Private Sub ManuallyAddValues(ByRef Values As IOrderedDictionary)
        For Each Field As Core.Field In FormView1.DataSourceControl.IncludedFields
            If Values(Field.Name) Is Nothing Then
                Dim DataboundControl As Control = FormView1.FindControl("FormRows").FindControl(Field.Name)
                Values.Add(Field.Name, GetValue(DataboundControl))
            End If
        Next
    End Sub

Questo non è così elegante, perché

  1. Devo conoscere i nomi di tutti i controlli databound
  2. Questo si basa sul presupposto che l'ID di ogni controllo corrisponde al nome di campo
  3. La funzione 'GetValue' (non incluso qui) è una soluzione goffa: verifica di vari tipi (testo, DropDownList, casella di controllo, etc.) e ottiene il valore della stringa dalla proprietà appropriata (TextBox.Text, dropdownlist.selectedvalue , checkbox.checked, etc.).

Mi piacerebbe ancora l'amore per avere almeno un modo di conoscere ciò che è legato con il '<% # Bind ( 'Pippo')%>' sintassi e ottenere direttamente le informazioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top