Cambia in modo dinamico il controllo utente in ASP.Net

Sto cercando di creare una pagina Web che visualizzerà un controllo utente appropriato in base al valore selezionato di un elenco a discesa.

Fondamentalmente il layout della pagina è questo:

Selezione a discesa
< Controllo utente creato in base alla selezione a discesa >

L’ho fatto a metà … i controlli stanno cambiando quando la selezione cambia. In OnInit (), creo dynamicmente l’ultimo controllo selezionato (il cui valore viene salvato nello stato di sessione perché ViewState non è disponibile su OnInit).

Quando si verifica la modifica della selezione a discesa, rimuovo il vecchio controllo utente e ne aggiungo uno nuovo. Il problema è: con il nuovo controllo aggiunto dall’evento modificato di selezione, non sono in grado di salvare le modifiche dall’utente sul primo postback . Dopo il primo post, il controllo selezionato viene creato da OnInit anziché dall’evento Change e lo stato viene salvato da quel momento in poi, fino alla successiva modifica della selezione.

Ecco il metodo SelectionChanged:

protected void SelectionChanged(object sender, EventArgs e) { SelectedValue = int.Parse(DropDownList.SelectedValue); //Store in Session Control userControl = GetSpecificUserControl(SelectedValue); PlaceHolder1.Controls.Clear(); // Remove old user control PlaceHolder1.Controls.Add(userControl); } 

Eventuali modifiche apportate al nuovo controllo da parte dell’utente dopo aver effettuato SelectionChanged non vengono salvate sul seguente post. Tuttavia, i postback successivi vengono salvati. A quel punto, il controllo viene creato in OnInit ().

C’è un modo per forzare il post corretto e ViewState quando il controllo cambia? È ansible forzare la reinizializzazione di una pagina dopo la modifica del controllo?

Questo è il classico problema dei lacrimogeni con i Webform ASP.Net. Hai diverse opzioni:

1) Questo è un po ‘un trucco, dal momento che va un po’ al di fuori del ciclo di vita previsto della pagina, ma nella mia esperienza è il modo più diretto di affrontare il problema. Quando la pagina torna indietro dall’evento di selezione a discesa, Request["MyDropDownID"] semplicemente Request["MyDropDownID"] per il valore selezionato del controllo a discesa durante Init() – non aspettare l’evento OnMyDropDownChanged() per impostare la pagina.

2) Implementa la tua gestione ViewState per i tuoi controlli utente. Ciò richiede di scavare nella documentazione di ViewState e sovrascrivere un certo numero di metodi.

3) Soluzione di Joel. Mi ha battuto ma stavo cercando di ottenere il primo post: p

Altre opzioni implicano la pubblicazione di valori usando javascript e simili, ma quelli diventano veramente disordinati.

Quello che devi fare è mantenere l’ultimo valore conosciuto di DropDownList nella Session. Poi:

OnInit:

  • Crea qualsiasi controllo è indicato dal valore salvato nella sessione

Evento SelectionChanged

  • Rimuovi qualsiasi cosa tu abbia creato durante OnInit
  • Crea e aggiungi nuovi controlli in base alla nuova selezione DropDownList
  • Salva la nuova selezione DropDownList nella sessione

In questo modo, nel prossimo postback dopo una modifica, stai ricreando il controllo che si aspettava di trovare da ViewState, quindi verrà ripristinato lo stato.

I controlli dinamici possono essere molto schizzinosi. Spesso è più facile creare tutti i controlli che potrebbero essere necessari e impostare le proprietà Visible su false. In questo modo non rendono affatto il browser. Quindi imposta Visible su true per i soli controlli di cui hai bisogno quando ne hai bisogno.

Se l’elenco di opzioni non è troppo grande, puoi semplicemente eseguire il rendering di tutti i controlli utente in modo statico e utilizzare JavaScript / jQuery per mostrare / hide i controlli appropriati in base al valore del menu a discesa (evento onchange js). È ansible utilizzare il valore del menu a discesa per estrarre i valori appropriati dai controlli utente durante il salvataggio.

Evita il dolore di gestire i controlli dinamici, fornisci un’interfaccia utente più retriggers quando selezioni dal menu a discesa (senza postback), ecc …

Non aggiungere il controllo nel gestore SelectedIndexChanged, aggiungilo durante Page_Load. Dovrai solo testare il valore del menu a discesa ogni volta che la pagina viene caricata e caricare il controllo corretto per quel valore.