Ascx da ascx

mercoledì 02 ottobre 2013 - 21.58
Tag Elenco Tags  C#  |  .NET 4.0  |  Visual Studio 2002  |  Javascript  |  HTML 4.01

Ninja87 Profilo | Junior Member

Buonasera a tutti, avrei una piccola curiosità, avrei bisogno di creare un controllo ascx da un altro controllo ascx, in pratica dovrei creare una serie di controlli con una parte della grafica comune a tutti quanti, un po come funzionano le masterpage, sarebbe possibile farlo? se così non fosse come potrei ovviare al problema senza dover duplicare tutto il codice, html e cs in tutti i nuovi controlli? Spero di essere stato abbastanza chiaro e un grazie in anticipo.

andrestu Profilo | Expert

si puoi farlo, crei il controllo di base per la grafica e lo carichi all'interno di tutti gli altri

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

Ciao, grazie per la risposta, il problema, se ho ben capito cosa intendi, è che avrei bisogno di controlli con dei segnaposto, cioè l'header e il footer sono comuni a tutti i controlli, a me cambia il content e la parte in cui inserisco eventuali pulsanti del controllo

Ninja87 Profilo | Junior Member

dimenticavo di aggiungere che tutti i nuovi controlli sono controlli modali, per cui condividono il modalpopupextender

andrestu Profilo | Expert

si potresti creare un UC per l'header e un UC per il footer e la dove vorrai utilizzarli li inserirai, solo che per questo scopo esistono le master-page non capisco perchè non le utilizzi

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

le masterpage, da quello che ho capito, funzionano per le pagine aspx a me invece serve per i controlli ascx, però correggimi se sbaglio

andrestu Profilo | Expert

si ok ma perchè devi usare dei UC invece della masterpage?

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

perchè sono schermate modali per l'inserimento dei dati che appaiono sopra la pagina vera e proprio, schermate draggabili

andrestu Profilo | Expert

a ok, scusa per curiosità come li carichi dinamicamente i UC nella pagina, tramite il modalpopupextender ?

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

si esatto e tramite l'utilizzo della funzione LoadControl

andrestu Profilo | Expert

scusa in che modo utilizzi LoadControl ?
immagino all'interno di un evento della pagina e poi successivamente assegni l'ID del UC caricato ad una proprietà del ModalPopupExtender giusto?

Ninja87 Profilo | Junior Member

in pratica faccio
Controllo ctrl = LoadControl("/ui/controllo.ascx") as Controllo;
poi in ctrl imposto tutte le relative proprietà e faccio l'aggiunta ad un placeholder posizionato dentro un updatepanel (nella pagina chiamante) in modo da avitare il full postback della pagina, il modalextender risiede in "Controllo" che in associazione con un panel mi permette di spostare la form all'interno della pagina

andrestu Profilo | Expert

che macello,
ma non si può direttamente da un modalPopupExtender caricare dinamicamente un UC e farlo apparire dentro un popup ?

Ninja87 Profilo | Junior Member

Ahahahah si il mondo m$ non è proprio dei più semplici scherzi a parte, il modalpopupextender serve per simulare una schermata modale, draggabile o meno, di un asp panel

andrestu Profilo | Expert

ok in verità la mia domanda era per sapere se c'è la possibilità di caricare dinamicamente (al click di un pulsante) un UC e mostrarlo all'interno di un modal popup il tutto all'interno di un updatepanel, se devo dirla tutto io questo comportamento me lo sono creato ad hoc estendendo il ModalPopupExtender però mi è venuto il dubbio che forse è un comportamento già previsto dal controllo...

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

ah ok scusa, beh, più o meno è quello che faccio, nel senso che alla pressione di un pulsante che risiede sulla pagina viene istanziato il controllo al placeholder (e quindi all'updatepanel) sempre sulla pagina, che io sappia non c'è modo di caricare direttamente dall'extender, per curiosità tu come lo hai fatto?

andrestu Profilo | Expert

ho esteso la classe del ModalPopupExtender e ho integrato tutti i metodi e proprietà di cui avevo bisogno, praticamente io per caricare un controllo UC e visualizzarlo in un popup basta che dalla pagina faccio riferimento al ModalPopupExtender, imposto una proprietà che identifica il path del UC e chiamo il metodo Show() dell'extender e il gioco è fatto!!!
Comunque questo fa parte di un pacchetto contenente una serie di modifiche che ho fatto per sviluppare al meglio con Aspnet, il fatto è che alle volte magari implementi un meccanismo che poi lo trovi implementato con le nuove versioni dei controlli.
Ai tempi quando feci questa modifica probabilmente il ModalPopupExtender non permetteva di fare questo però forse con le ultime release degli AjaxControlToolkit è probabile che lo abbiano implementato, infatti mi è venuto il dubbio e pensavo che tu usassi questo meccanismo.
Quando avrò due minuti di tempo darò un occhio al tutorial degli ACT...

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

ok, allora proverò a giocare con la derivazione, anche se non molto ben capito che tipo di metodi hai aggiunto, per ora ti ringrazio molto per l'aiuto

andrestu Profilo | Expert

guarda niente di complicato, praticamente imposto l'extender in modo da far visualizzare un div, nel init dell'extender carico lo UC e lo inserisco all'interno del div e poi chiamo il metodo show dell'extender.
L'unica cosa è che ti devi inventare un meccanismo per il quale al postback l'extender carichi automaticamente lo UC altrimenti lo perderesti.
Puoi per esempio appoggiarti ad una proprietà che utilizza il ViewState, la valorizzi con il path del UC che vuoi caricare così al postback l'extender se trova la proprietà valorizzata carica automaticamente lo UC.

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

mmm, in effetti è interessante come idea, non ci avevo pensato, solo un'ultima curiosità (lo so sono insistente è che sto cercando di apprendere nuove tecniche di programmazione), come te la cavi con i parametri dello UC, cioè nell'extender posso mettere una proprietà path e riuscire a ricaricare il controllo, però ogni controllo avrà N proprietà pubbliche che devono essere impostate per farlo funzionare, come si può fare, far diventare l'extender come template e passargli una struttura con i valori?

andrestu Profilo | Expert

no basta che esponi lo UC che hai caricato come se fosse una proprietà dell'extender, ovviamente la definisci come Control e poi quando ci accedi dall'esterno fai un cast al tipo di UC che hai caricato.
Comunque ci sono altri aspetti di cui ti devi preoccupare visto che dando un occhiata al controllo ho fatto caso che ho implementato diversi metodi e proprietà per farlo funzionare al meglio, in ogni caso se hai voglia di smanettare un pochino questo è il meccanismo di base che puoi provare ad implementare e ti garantisco che è molto comodo perchè io dalla stessa pagina carico e scarico visualizzando a popup qualsiasi UC di cui ho bisogno.
Prima però ti consiglio di andare a vedere il tutorial del ModalPopupExtender, questo perchè non è detto che questa funzionalità non l'abbiano già implementata con la versione 4 che è uscita non da molto.
Comunque appena ho un pò di tempo dovrei pubblicare sul mio sito questo e altre features per Aspnet

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

Perfetto, allora farò qualche piccolo esperimento, per il momento ti ringrazio tanto per l'aiuto

Ninja87 Profilo | Junior Member

ciao, scusa se ti disturbo nuovamente, non mandarmi a quel paese ma sono bloccato da 2 giorni su un piccolo problema, sono riuscito a fare un modalpopupetender con la stessa filosofia che dicevi tu e in effetti la cosa è molto più comoda, adesso riesco a caricare e scaricare controlli in maniera automatica senza dovermi preoccupare di ricaricarli, però mi sono imbattuto in un piccolo problema.
l'esempio pratico in questo momento è questo: il controllo che devo caricare si preoccupa di impostare una condizione per una query select, tuttavia quando eseguo l'evento close all'interno dell'extender (ciò dovrebbe fare l'aggiornamento di un updatepanel in cui è presente una gridview) la griglia rimane esattamente come si trova, nonostante il fatto che l'evento all'interno della pagina sia stato eseguito e che la condizione sia correttamente impostata.
ho provato a fare il debug e ho notato che il numero di righe all'interno della griglia sono quelle che effettivamente mi aspetto, però la vista non cambia, sapresti come risolvere questo problema?
spero di essere stato sufficientemente chiaro e ti ringrazio in anticipo per ogni tuo aiuto

andrestu Profilo | Expert

non ho capito molto bene la struttura della pagina comunque provo a risponderti.
la gridview e l'extender si trovano su due update panel differenti ? perchè in tal caso potrebbe essere semplicemente un problema di aggiornamento dell'update panel, se così fosse prova a chiamare manualmente il metodo update dell'update panel

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

grazie per non avermi mandato a quel paese ho eseguito una struttura un pochino complicata, provo a riassumerla, in pratica ho creato un'interfaccia che espone una serie di metodi e proprietà, tutti i controlli che devono essere caricati attraverso l'extender devono derivare da questa interfaccia, perchè poi l'extender sfrutta proprio tutti quei metodi e proprietà e fino a qui nulla di complicato, ora, per una questione di praticità ho creato un updatepanel con un panel e l'extender dentro la master page, in modo da accedervi da tutte le pagine e page1.aspx (che fa uso della suddetta masterpage) richiama il controllo, tutto ciò avviene in maniera perfetta, tuttavia come ti dicevo non avviene l'aggiornamento della griglia (nell'updatepanel) in page1.aspx, anche facendo uso dell'updamode conditional e chiaramente richiamando il metodo update

andrestu Profilo | Expert

he he heee guarda è grosso modo anchio uso questa struttura, l'extender all'interno di un update panel differente configurato come conditional, quando carico lo uc tramite l'extender ovviamente aggiorno anche l'update panel...
tornando al tuo problema intanto bisognerebbe capire se il problema è causato dal gridview o dalla struttura, prova a caricare un UC con dei controlli di test all'interno che ne so per esempio una textbox con un button e al click del button aggiorni il text della tetxbox e vedi se funziona il tutto regolarmente, se funziona allora il problema è identificabile nel gridview, prova a chiamare il databind manualmente...

andrestu Profilo | Expert

occhio anche agli eventi, cerca di caricare lo UC all'interno dell'evento Init dell'extender...

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

bene per cui non ho sbagliato come filosofia di fondo mi è venuto il dubbio che il problema fosse l'updatepanel (mi è venuto in mente solo ora), perchè mi sono creato un ascx che simula controllo pager per la gridview, inserito anch'esso all'interno dell'updatepanel della pagina page1.aspx (insieme alla griglia) e ho notato che non si aggiorna neanche quello, ripensando ho notato questo, all'interno dell'extender ho creato un evento close per eseguire determinate operazioni quando viene eseguito il metodo Hide però ho notato che al primo passaggio l'handler è correttamente inizializzato al secondo passaggio vale null, per cui ho provato a salvare l'handler all'interno della session e riassegnarlo di volta in volta, però mi chiedevo, non è che l'evento viene poi eseguito su un instanza diversa di page1.aspx?

Ninja87 Profilo | Junior Member

dimenticavo, l'UC viene caricato all'interno del metodo init

andrestu Profilo | Expert

scusa faccio un pò fatica a seguirti perchè non avendo sotto gli occhi tutta la struttura è un pò difficile ricrearsela mentalmente, ti dico come mi comporto io forse questo ti può aiutare.
Per quanto riguarda le proprietà del UC non cè problema perchè le valorizzazione anche solo alla prima apertura del UC, nei successivi postback tanto vengono recuperate tramite viewstate.
Per quanto riguarda invece gli eventi assegnati dinamicamente dall'esterno del UC la questione è leggermente diversa, ammettiamo che nel UC cè un button al quale voglio fare eseguire un metodo al click, però l'evento lo voglio assegnare dall'esterno del UC quindi dalla pagina, dovrò per forza di cose riassegnarlo ad ogni postback quindi all'init della pagina verifico se l'UC è presente e in tal caso assegno l'evento (es. Button_OnClick), potrei anche appoggiarmi alla sessione ma sinceramente non ho optato per questo meccanismo, se posso cerco di essere slegato dalla sessione tanto comunque concettualmente sono sempre settaggi impostati dall'esterno del controllo quindi che li imposto in un solo punto della pagina o in due fa poca differenza.
Per quanto riguarda il discorso della sessione l'oggetto sarà sempre lo stesso sia che ci accedi da pagina1 che pagina2 o altro punto, quindi se usi la sessione come meccanismo di supporto per il salvataggio ricordati di svuotare la relativa key della sessione ogni volta che apri un nuovo UC, altra cosa che devi fare attenzione è che la sessione è soggetta a scadenza il viewstate no.
ti sono stato di aiuto?

Andrea Restucci - Web Developer

andrestu Profilo | Expert

altro suggerimento di implementazione generale su come mi sono impostato il template di lavoro:
anche io prima usavo l'extender all'interno di una master-page in comune con tutte le pagine, ultimamente però lho spostato in un UC dedicato, quindi in una classe personale derivata da page carico ad ogni avvio questo UC dedicato che funge un pò come se fosse un centro di controllo anche per altri compiti, fatto questo basta che in qualsiasi pagina al posto di page come classe derivata uso la mia classe e il gioco è fatto. in questo modo sono completamente slegato dalla master-page.
l'unica cosa che non sono riuscito a fare è caricare da questo UC lo script manager, infatti quello lo devo inserire nella master-page nel classico modo, però a parte questo tutto il resto è finito in questo UC dedicato.
ti piace come soluzione?

Ninja87 Profilo | Junior Member

se ti resta più comodo lunedì mattina posso provare a postarti il codice, sia dell'interfaccia, sia dell'extender così ti rendi conto di tutto quello che ho fatto. la session la svuoto nel metodo hide, però forse come dici tu se non vedi il codice è difficile immaginarsi il tutto

andrestu Profilo | Expert

si manda se non è troppo articolato posso darci un occhio solo che se è in VB non ci capisco una mazza, dovresti prima tradurlo in C#

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

ahahahahah, no tranquillo per fortuna è in c# allora lunedì mattina te lo posto così mi dici cosa ne pensi

Ninja87 Profilo | Junior Member

ciao, allora questa è classe derivante da ModalPopupExtender

public class ModalExtenderAutoLoad : ModalPopupExtender { /// <summary>Evento scatenato alla chiusura del controllo</summary> public event EventHandler<EventArgs> Close = null; /// <summary>Legge/Imposta l'evento Close (salvataggio per non perderlo nel postback)</summary> private EventHandler<EventArgs> CloseEvent { get { return GetSessionData("CloseEvent") as EventHandler<EventArgs>; } set { SetSessionData("CloseEvent", value); } } /// <summary>Legge/Imposta il percorso del controllo da caricare</summary> public string Path { get { return GetSessionValue("PopupExtenderAutoLoadPath"); } set { SetSessionValue("PopupExtenderAutoLoadPath", value); } } /// <summary>Legge/Imposta l'eventuale classe con i parametri per il controlo</summary> private object Parameters { get { return GetSessionData("ParametersLoadPath"); } set { SetSessionData("ParametersLoadPath", value); } } /// <summary>Legge/Imposta l'oggetto derivante dall'interfaccia IModalForm</summary> private IModalForm Form { get { return GetSessionData("FormAutoLoadPath") as IModalForm; } set { SetSessionData("FormAutoLoadPath", value); } } /// <summary>Legge/Imposta il colore del pannello</summary> public Color PanelColor { get { return (Color)(GetSessionData("PanelColorAutoLoad") ?? Color.White); } set { SetSessionData("PanelColorAutoLoad", value); } } protected override void OnInit(EventArgs e) { base.OnInit(e); if (!Page.IsPostBack) ClearParam(); if (!Path.IsNullOrEmpty()) Show(); } /// <summary>Rimuove il path e la lista dei parametri</summary> private void ClearParam() { Path = ""; Parameters = null; } /// <summary>Ritorna i dati della sessione con la chiave specificata</summary> /// <param name="key">Chiave dei dati</param> /// <returns>I dati</returns> private object GetSessionData(string key) { return Global.Current.GetSessionData(key); } /// <summary>Ritorna il valore della sessione con la chiave specificata</summary> /// <param name="key">Chiave del valore</param> /// <returns>Il valore</returns> private Any GetSessionValue(string key) { return Global.Current.GetSessionValue(key); } /// <summary>Imposta i dati della sessione con la chiave specificata</summary> /// <param name="key">Chiave del valore</param> /// <param name="data">Dati da usare (default elimina la chiave)</param> /// <returns>L'esito</returns> private bool SetSessionData(string key, object data = null) { return Global.Current.SetSessionData(key, data); } /// <summary>Imposta il valore della sessione con la chiave specificata</summary> /// <param name="key">Chiave del valore</param> /// <param name="value">Valore da usare (default elimina la chiave)</param> /// <returns>L'esito</returns> private bool SetSessionValue(string key, Any value = default(Any)) { return Global.Current.SetSessionData(key, value.GetValue()); } /// <summary>Carica il controllo</summary> new public void Show() { if (Close != null) CloseEvent = Close; else if (CloseEvent != null) Close += CloseEvent; Form = Page.LoadControl(Path) as IModalForm; if (Form == null) throw new GenericException("Il controllo non deriva dall'interfaccia IModalForm"); if (Parameters != null) Form.InitParameters(Parameters); Control ctrl = (Control)Form; ctrl.ID = Form.ColtrolID.ValidString("AutoLoadControl"); IMasterPage master = (IMasterPage)Page.Master; master.PanelForm.Controls.Add(ctrl); master.PanelForm.BackColor = PanelColor; master.UpdatePanelForm1.Update(); if (!Form.DragId.IsNullOrEmpty()) master.PopupExtender.PopupDragHandleControlID = Form.DragId; base.Show(); } /// <summary>Rimuove il controllo</summary> new public void Hide() { ClearParam(); base.Hide(); RemoveControl(); OnClose(this, Form.CloseArgs ?? EventArgs.Empty); Form = null; CloseEvent = null; } protected virtual void OnClose(object sender, EventArgs e) { if (Close != null) Close(this, e); } /// <summary>Rimuove il controllo dall'updatepanel</summary> private void RemoveControl() { IMasterPage master = (IMasterPage)Page.Master; master.PanelForm.Controls.Clear(); master.UpdatePanelForm1.Update(); } /// <summary>Imposta la classe con i parametri per l'oggetto da caricare</summary> /// <typeparam name="T">Tipo della classe</typeparam> /// <param name="param">Classe da impostare</param> public void SetParameters<T>(T @param) where T : class { Parameters = param; } }

questa è l'interfaccia da cui devono derivare tutti i controlli

/// <summary>Interfaccia per le form caricate dinamicamente</summary> public interface IModalForm { /// <summary>Id dell'oggetto per il drag della finestra</summary> string DragId { get; } /// <summary>Id del controllo</summary> string ColtrolID { get; } /// <summary>Evento chiusura</summary> EventArgs CloseArgs { get; set; } /// <summary>Imposta la classe con i parametri</summary> /// <param name="param">Classe dei parametri</param> void InitParameters(object param); }

e questo è come richiamo il tutto

protected void cmdFind_Click(object sender, EventArgs e) { // Controllo che sia stato selezionato un archivio if ((!TableName.IsNullOrEmpty()) && (ColumnsArchive != null) && (ColumnsArchive.Count >= 1)) { ModalExtenderAutoLoad autoLoad = ((IMasterPage)Page.Master).PopupExtender; autoLoad.Path = "/UI/FieldFilterControl.ascx"; autoLoad.SetParameters(new ParamFilter { ColumnsArchive = ColumnsArchive }); autoLoad.Close += (caller, args) => { CloseWithClearEventArgs args1 = args as CloseWithClearEventArgs; switch (args1.ButtonPressed) { case ButtonChoiceWithClear.Clear: case ButtonChoiceWithClear.Confirm: ClearSelectedDocument(); // Riaggiorno la griglia con l'imposatzione del where FillGridView(); break; } }; autoLoad.Show(); } }

sono veramente in alto mare se riesci a darmi una mano te ne sarei molto grato. grazie in anticipo

andrestu Profilo | Expert

ciao senti non riusciresti a mandarmi un piccolo progettino (io uso VS2010 ma anche il 2008 va bene) con tanto di pagina di test con controllo inserito, giusto l'essenziale per fare un pò di debug, così mi risparmi "un pò di lavoro"... grazie

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

Ciao, scusa se rispondo solo ora ma ho impiegato un pochino per fare un progetto di prova, allora nel progetto allegato ho fatto un piccolo test di quello che dovrebbe venir fuori, escludendo temi e altre cose non essenziali, tieni presente che il progetto originario, cioè quello che sto sviluppando, ha molte cose collegate e che purtroppo per motivi aziendali non posso divulgare, ad esempio il collegamento ad un db, per evitare questa cosa ho utilizzato il linq, per cui ho dovuto riadattare diverse cose, spero solo di non aver dimenticato di aggiungere nulla

andrestu Profilo | Expert

mmm è un problema sull'aggiornamento manuale dell'update panel che contiene il grid, ricordo di averlo già riscontrato in passato e ricordo anche di averlo risolto, ma non capisco ora dove devo intervenire...

l'eccezione è questa:
The Update method can only be called on UpdatePanel with ID ... before Render.

apparentemente la struttura del mio modal segue le stesse operazioni del tuo eppure con il mio progetto non riscontro il problema.
Praticamente con il tuo progetto se provi ad aggiornare il grid in qualsiasi momento escluso quando fai la chiusura dell'extender funziona tutto regolarmente, se invece lanci il metodo update() durante la chiusura dell'extender viene generata l'eccezzione... mmmmmmmmmmm..... non mi arracapezzolo !!!
cazzo sto vizio di non segnarmi le cose!!!
vedo se riesco a capirci qualcosa intanto fai qualche ricerca sull'eccezione e vedi se riesci a trovare un sugg.



Andrea Restucci - Web Developer

andrestu Profilo | Expert

ok ho risolto, praticamente ho spostato la chiamata al metodo hide() e così funziona, ovviamente questa è una bozza, ho dovuto un pò "pasticciare il tutto" per capire dove intervenire, ora devi svilupparti una soluzione strutturata.
ti allego il progetto modificato

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

mamma mia, questa mattina sono veramente duro di comprendonio, ho visto che effettivamente con il tuo metodo funziona, cioè chiamando la funzione di aggiornamento della griglia in maniera diretta dal controllo, ora però non capisco perchè dichiarando l'evento la cosa non funziona allo stesso modo

andrestu Profilo | Expert

guarda non sono stato ad indagare più di tanto però a quanto pare la cosa che fà la differenza pare che sia il punto in cui chiami l'update() nella fase del ciclo della pagina, cioè devi capire se la differenza lo fà il punto in termini di sequenza di eventi oppure in termini di classe da dove lo chiami, o è uno o l'altro che provoca l'eccezione... io normalmente chiamo il metodo update() dalla pagina, quindi all'interno dell'evento click del pulsante, evento però assegnato dalla pagina, così non ho problemi...
io però lo assegno direttamente al pulsante esponendolo come proprietà del UC o dell'extender, fai questa prova, esponi il pulsante direttamente come proprietà e prova ad assegnargli un evento classico del tipo click

Andrea Restucci - Web Developer

andrestu Profilo | Expert

...e magari procedi a step, ho visto che salvi l'evento in session, prova prima ad assegnarlo manualmente ad ogni postaback dall'evento init della pagina e poi se tutto funziona procedi ad attivare l'automatismo.
ti consiglio di fare dei test riducendo il tutto "all'osso" leva tutto il superfluo così rieci ad individuare meglio il punto critico


Andrea Restucci - Web Developer

andrestu Profilo | Expert

fammi sapere

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

niente, da questa mattina fino a questo momento non sono riuscito a trovare un modo per farlo funzionare come dovrebbe

andrestu Profilo | Expert

guarda stasera se trovo un buco di tempo libero mi ci metto

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

se non riesci tranquillo non importa, però te ne sarei estremamente grato perchè sto impazzendo

Ninja87 Profilo | Junior Member

allora, dopo 4 gg di pena, forse sono riuscito a risolvere il problema, da quello che mi sembra di aver capito gli eventi sono comunque costretto a riassegnarli ad ogni postback nell'init della pagina, non posso impostarli una volta nel click del pulsante e poi basta per cui l'init della pagina l'ho fatto così

protected override void OnInit(EventArgs e) { base.OnInit(e); ModalExtenderAutoLoad autoLoad = ((IMasterPage)Page.Master).PopupExtender; if (autoLoad.Ctrl != null) { if (autoLoad.Ctrl is FieldFilterControl) ((FieldFilterControl)autoLoad.Ctrl).ConfirmClick += (caller, args) => FillGridView(); } }

anche se non so se è ottimizzabile e sono stato costretto a modificare pesantemente anche l'oggetto che si occupa del caricamento degli oggetti ascx

andrestu Profilo | Expert

scusa ma ancora non sono riuscito a guardarlo, sono un pò carico di lavoro, comunque così è ok, anchio uso la stessa tecnica.
La tua idea (salvare in session l'evento) però era buona, io non ci ho mai provato ad implementarla però forse quando avrò un pò di tempo ci proverò.
Vedo che non è cambiato molto da prima quindi il problema dell'aggiornamento dell'update forse era dovuto al fatto che l'evento veniva valorizzato dalla session anche se non capisco come mai, non ci vedo nessun problema in questa operazione. avrei dovuto fare un pò di analisi supplementare per capire dove stava il cavillo...
magari se trovo un minuto ci provo

in alternativa potresti evitare di riassegnare il click ad ogni postback e fare tutto dal UC magari passandogli i relativi oggetti di cui ha bisogno, anche se concettualmente secondo me è sbagliato, lo UC dovrebbe essere più indipendente possibile in modo da poterlo riutilizzare anche in altri contesti.

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

no no tranquillo non ho scritto perchè ancora non mi avevi risposto, ho voluto solo condividere la soluzione che avevo trovato, nonostante io sia sia sicuro che di soluzioni fatte meglio ce ne siano molte.
da quello che ho capito il salvataggio dell'handler nella session non va bene, poichè ad ogni postback verranno cambiati alcuni riferimenti interni, di conseguenza verrà visualizzato il messaggio di errore che avevi postato tu, sul'aggiornamento prima del prerender (ora non ricordo la stringa esatta, PS: complimenti alla M$ per il quantitativo di documentazione che si trova su questo errore ).
ci avevo pensato di passare degli oggetti specifici all'ascx però ho fatto il tuo stesso ragionamento, quando posso cerco di creare usercontrol più astratti possibile in modo da potermeli riutilizzare diverse volte.

è stato un parto ma ci siamo riusciti o almeno una delle migliaia di soluzioni è stata trovata

andrestu Profilo | Expert

si ma era interessante capire se si trovava il modo, ci ho riprovato ma nulla da fare, in effetti succede qualcosa di strano, qualcosa che rientra nel "paranormale"
allora ho impostato il tutto in modo di salvare l'handler in session e assegnarlo direttamente al pulsante nell'evento init, ho provato ad impostare un bool nella pagina
bool performUpdate = false;
poi all'interno del metodo che aggiorna la grid invece di chiamare l'aggiornamento del UP imposto a true la variabile performUpdate, poi ho messo nell'evento della pagina Page_LoadCompete (evento che viene scatenato subito dopo il click) un controllo che verifica se la variabile performUpdate e true allora chiama l'aggiornamento dell'UP.
la cosa strana che succede è che la variabile rimane sempre su false!!!

comunque ti chiedo io una cosa che non centra niente, ho visto che nell'header usi una sintassi del tipo
<%:

visto che io ho sempre usato o
<%#
oppure
<%=

a cosa serve <%: ?

Andrea Restucci - Web Developer

Ninja87 Profilo | Junior Member

in pratica, se ho capito bene, hai riprodotto esattamente quello che avevo fatto io inizialmente, infatti succede qualcosa che non mi torna del tutto, in base a quel poco che sono riuscito a trovate in rete dovrebbe essere qualche riferimento che cambia, però e questo potrebbe starmi bene, però tramite il viewstate lui non dovrebbe reimpostare proprietà ed eventi in base all'associazione dell'id?
aspetta, dove si trova, "<%:", in questo momento, non riesco a ritrovarlo

andrestu Profilo | Expert

a dimenticavo, ti do altre indicazioni che potrebbero esserti utili in quei casi in cui devi caricare lo UC e devi valorizzare delle sue proprietà dalla pagina prima dell'evento Init del UC stesso
1 - in rete si trova l'estensione del metodo LoadControl che permette di passare anche parametri al costruttore, quindi può tornare utile
2- altra soluzione, una modifica che ho fatto oggi stesso: implementa due metodi separati nell'extender uno il Loadcontrol che carica effettivamente il controllo e l'altro (che hai già) lo Show dove andrai ad inserire il controllo caricato nel container di riferimento, qual'e il vantaggio?
il vantaggio è quello di poter vaolrizzare le proprietà del UC prima che venga scatenato l'Init del UC stesso, questo perchè quando chiami il metodo LoadControl il controllo viene caricato ma gli eventi ancora non sono stati scatenati, vengono scatenati al momento dell'inserimento in un controllo della pagina, quindi quando fai MioContainer.Controls.Add(...

spero di esserti stato utile
ciao alla prox


Andrea Restucci - Web Developer

andrestu Profilo | Expert

rispondo all'ultimo tuo quesito:
non ho capito bene, il viewState in questo caso non centra nulla, probabilmente succede qualcosa che lo fà andare in "tilt" quando richiami un handler precedentemente salvato in session.
Per quanto riguarda il viewstate ho fatto caso spesso che non riesco ad usarlo direttamente con una proprietà dello UC, invece se mi appoggio ad un controllo inserito nell UC non cè problema, il viewstate dei controlli viene correttamente inizializzato, infatti alle volte mi appoggio ad un HiddenField.
Ammettiamo di far funzionare un proprietà dello UC con il viewstate, si potrebbe provare a salvare l'handler nel viewstate anche se non credo che possa funzionare, probabilmente l'handler non è serializzabile

questo <%: si trova nel primo progetto che mi hai inviato

Ninja87 Profilo | Junior Member

allora avevo capito male il viewstate, quello purtroppo è un meccanismo che mi rimane ancora molto ostico, è per quello che utilizzo Session.
si, in effetti nonì avevo pensato al fatto che LoadControl ha un overload che accetta due parametri, se non erro uno è il tipo del controllo e l'altro è un array di parametri, in effetti potrebbe tornare utile per evitare il metodo InitParameters nell'interfaccia e quindi nel controllo, si grazie questo mi può tornare utile.
per quando riguarda <%: tu dici quando dichiaro

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

se intendi questo è semplicemente un altro modo di dichiarare <%=
cmq sia ti ringrazio tantissimo per l'aiuto che mi hai dato e mi scuso se ti ho fatto perdere tempo, alla prossima

andrestu Profilo | Expert

il viewstate è semplicemente un meccanismo che ti permette di persistere le proprietà dei vari controlli tra un postback e l'altro

Andrea Restucci - Web Developer
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5