2009-09-14 10 views
5

Per semplificare la creazione di una determinata forma, viene utilizzato un controllo Formview modificato all'interno di un controllo utente. Questo controllo utente è per una griglia e un FormView, è possibile scegliere una voce nella griglia, e un FormView è presentato in una modale per la visualizzazione/modifica:Come esporre un ITemplate tramite un controllo utente?

<I2CL:Grid runat="server" ID="Grid" OnSelecting="Selecting" ShowCreate="true" /> 
<I2:Modal ID="SFModal" runat="server" UpdateMode="Conditional"> 
<ContentTemplate> 
    <I2:FormView runat="server" ID="FVSubForm" DefaultMode="Edit" DataSourceID="DSSubForm" /> 
    <I2:ILDataSource ID="DSSubForm" runat="server" /> 
</ContentTemplate> 
</I2:Modal> 

In una pagina, il controllo è simile al seguente:

<I2C:TabGrid ID="TG" runat="server" Property="ParentProperty"> 
    <Columns> 
    <I2:Column Header="Column 1" DataSource="Column1" /> 
    <I2:Column Header="Column 2" DataSource="Column2" /> 
    </Columns> 
    <EditItemTemplate> 
    <I2Form:Dropdown ID="Col1" runat="server" SelectedValue='<%# Bind("Column1") %>' List="Column1Options" /> 
    <I2Form:Textbox ID="Col2" runat="server" Text='<%# Bind("Column2") %>' /> 
    </EditItemTemplate> 
</I2C:TabGrid> 

Il problema è il parametro EditItemTemplate che utilizziamo. L'unico modo per capire come agganciarlo è di avere un ITemplate nel controllo TabGrid e applicare il riferimento in OnInit:

[PersistenceMode(PersistenceMode.InnerProperty), 
TemplateContainer(typeof(FormView))] 
public ITemplate EditItemTemplate { get; set; } 

protected override void OnInit(EventArgs e) 
{ 
base.OnInit(e); 
FVSubForm.EditItemTemplate = EditItemTemplate; 
} 

Il problema è che, poiché il riferimento è ad un oggetto nel controllo utente, il riferimento EditItemTemplate che si collega alle voci del dizionario in FormView per le modifiche vengono distrutti, quindi quando si ottiene il dizionario delle modifiche inviate all'origine dati, esse sono vuote su ogni postback.

I2: ILDataSource utilizzato qui è un'implementazione personalizzata più vicina a ObjectDataSource. Invece di una chiamata di oggetto generico, chiama direttamente un GetEntity() nella pagina (o il controllo utente in questo caso) e un UpdateEntity(obj Entity) da salvare. Poiché si tratta di uno scenario molto specifico, possiamo eliminare il 90% del codice in ObjectDataSource.

Quello che voglio essere in grado di fare è puntare il <EditItemTemplate> nella <I2C:TabGrid> direttamente al <EditItemTemplate> del <I2:FormView> all'interno. È possibile, o qualcuno ha suggerimenti su un'altra strada da percorrere?

Nota: ho provato a esporre EditItemTemplate su FVSubForm come proprietà proxy, ma ciò non ha funzionato perché la proprietà è impostata sul controllo utente prima che venga creato il controllo figlio, quindi FVSubForm è null. Se questo può essere risolto, sono certamente tutte orecchie.

risposta

5

Una cosa che devi fare è segnare la vostra proprietà ITemplate a supportare due vie databinding:

[TemplateContainer (typeof (FormView), System.ComponentModel.BindingDirection.TwoWay)]

Senza questo, ASP.NET non genererà il codice corretto per la pagina che consente alle espressioni Bind() di funzionare.

Non sono sicuro che sia tutto ciò che serve, ma è qualcosa da provare.

David

+0

Grazie per il suggerimento ... ma la situazione è questa: l'ITemplate sé nel controllo utente non viene legato, è l'ITemplate sul controllo FormView che è assegnato a che qualsiasi legame si verifica su ... ha gli attributi di binding appropriati impostati. Ho provato comunque, ma nessuna differenza sul risultato finale (valori di aggiornamento vuoti) –

+0

Sebbene questo non fosse il problema diretto, si trattava di un proxy di associazione non propagante, l'ITemplate a cui era collegato il controllo utente non supportava correttamente associazione bidirezionale ... poiché la griglia non è direttamente modificabile, non ho mai notato questo comportamento Eval() solo in corso in tutto ciò che è sotto. Grazie David, punti di generosità per te! –

+0

Grazie Nick. Vorrei aver commesso una condizione di errore per provare a utilizzare Bind() in scenari in cui non farà nulla perché ITemplate non è contrassegnato correttamente. Se sei curioso, dai un'occhiata al codice generato per la pagina con e senza il flag TwoWay.Con il flag, vedrai apparire un metodo __ExtractValues__ completamente nuovo, che ha tutta la logica per far funzionare Bind(). –

Problemi correlati