ecco un pò di codice

questo da mettere nel pageload

if(this.ViewState["buttonCreated"] != null)
      {
        Button button=  new Button();
        button.ID = "button";
        button.Text = "un qualsiasi controllo";
        PlaceHolder1.Controls.Add(button);

      }


quasi speculare quello da aggiungere al gestore cel click


if(this.ViewState["buttonCreated"] == null)
      {

          Button button=  new Button();
          button.ID = "button";
          button.Text = "un qualsiasi controllo";
          PlaceHolder1.Controls.Add(button);
          this.ViewState["buttonCreated"] = 1;
      }


il valore da memorizzare nel ViewState in questo caso non è importante.

ciao marco

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx
146 messaggi dal 09 marzo 2005
funziona! ma sto rilevando una cosa strana.

Quando navigando nelle voci del menu (ogni bottone carica un controllo e scarica gli altri) ho rilevato che il controllo caricato è inerte nel primo evento (quando clicco su un bottone del controllo, la prima volta viene generato un postback a 'vuoto') poi funziona tutto regolarmente...

hai idea da cosa posssa dipendere?

ecco il codice con due tasti e due controlli. Alla pressione di un tasto viene caricato il relativo controllo e scaricato l'altro:

Private uc As Control

Private Sub Page_Load(...)

If Me.ViewState("fonti") <> "" Then
uc = Me.LoadControl("uc\stat_Fonti.ascx")
PlaceHolder1.Controls.Add(uc)
End If
If Me.ViewState("orarie") <> "" Then
uc = Me.LoadControl("uc\stat_Orarie.ascx")
PlaceHolder1.Controls.Add(uc)
End If

End Sub

Private Sub LinkButton1_Click(...)

Me.ViewState("orarie") = ""
Me.PlaceHolder1.Controls.Clear()
If ViewState("fonti") = "" Then
uc = Me.LoadControl("uc\stat_Fonti.ascx")
PlaceHolder1.Controls.Add(uc)
Me.ViewState("fonti") = "uc\stat_Fonti.ascx"
End If

End Sub

Private Sub LinkButton2_Click(...)

Me.ViewState("fonti") = ""
Me.PlaceHolder1.Controls.Clear()
If ViewState("orarie") = "" Then
uc = Me.LoadControl("uc\stat_Orarie.ascx")
PlaceHolder1.Controls.Add(uc)
Me.ViewState("orarie") = "uc\stat_Orarie.ascx"
End If

End Sub
è uno degli aspetti più noiosi dovuti al caricamento di molti controlli dinamicamente.

senza dilungarmi troppo, per generare un evento è necessario che l'albero dei controlli al postback sia ricreato esattamente come quello precedentemente salvato nel ViewState.

il primo consigli è quello di abilitare il trace della pagina e controllare l'albero dei controlli (scusa il gioco diparole) vedrai che l'albero cambia tra la prima volta che visualizzi il controllo e il postback che ti aspettavi generasse un evento.

se usavi asp.ner 2.0 per aiutarti nel debugging potevi usare il ViewStateAnlaizer di ricciolo

ciao marco

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx
146 messaggi dal 09 marzo 2005
ciao,

ho abilitato il trace x vedere cosa veniva fuori.

L'unica cosa che mi è sembrata 'strana' (ma non so sino a che punto) è che dopo che carico il secondo controllo sul placeholder (scaricando il primo) questo prende il nome _ct1... anzichè _ct0... nonostante abbia verificato che il controllo sul placeholder sia sempre uno... dopo il primo postback diventa _ct0 e poi funziona!

Bene se questo fosse il problema, come posso risolverlo?
senza scendere troppo nel dettaglio ti faccio un esempio:

creaimo due user control il primo chiamato UserControl1.ascx

aspx:
<asp:DropDownList id="sceglisito" runat="server" AutoPostBack="True">
  <asp:ListItem Value="1">aspitalia</asp:ListItem>
  <asp:ListItem Value="2">winfxitalia</asp:ListItem>
</asp:DropDownList>
<asp:Label id="messaggio" runat="server"></asp:Label>

codebheind:
private void DropDownList1_SelectedIndexChanged(object sender, System.EventArgs e)
    {
      messaggio.Text = sceglisito.SelectedValue;
    }


il secondo chiamato con fantasia

aspx:
<asp:LinkButton id="premimi" runat="server">premi</asp:LinkButton>
<asp:Label id="messaggio" runat="server"></asp:Label>

codebehind
private void premimi_Click(object sender, System.EventArgs e)
{
messaggio.Text="pulsante premuto";
}


sono due semplicissimi UserControl, il primo con una DropDownList e una label dove viene visualizzato all'verificarsi dell'evento SelectIndexChanged il valore dell'item selezionato.

il secondo ha un semplice LinkButton pemendolo viene visualizzato un messaggio nella Label.

ecco la nostra pagina.
public class WebForm1 : System.Web.UI.Page
  {
    protected System.Web.UI.WebControls.Button carica;
    protected System.Web.UI.WebControls.PlaceHolder inserisci;
  
    private void Page_Load(object sender, System.EventArgs e)
    {
      string contenuto = "UserControl1.ascx";
      if(this.ViewState["contenuto"] != null)
      {
        contenuto = (string)this.ViewState["contenuto"];
      }
      Control myControl = Page.LoadControl(contenuto);
      myControl.ID = "contenuto";
      inserisci.Controls.Add(myControl);
    }
    private void carica_Click(object sender, System.EventArgs e)
    {
      Control c = inserisci.FindControl("contenuto");
      if(c != null)
      {
        inserisci.Controls.Remove(c);
      }
      this.ViewState["contenuto"] = "UserControl2.ascx";
      Control myControl = Page.LoadControl("UserControl2.ascx");
      myControl.ID = "contenuto";
      inserisci.Controls.Add(myControl);
    }
  }


nel pageload controlliamo se è stato precedentemente caricato un UserControl, in questa eventualità recuperiamo il percorso da ViewStete e lo carichiami.

la pagina ha anche un buttone per caricare un altro UserControl.

alla pressione del bottone, cerchiamo l'eventuale UserControl caricato precedentemente, in quando il PageLoad viene sempre eseguito e sempre prima degli eventi chiamiamoli "utente".
se lo troviamo lo rimoviamo dalla collezione e al suo posto mettiamo quello nuovo.

così non si dovrebbero l'albero.

domani con meno sonno :) vedo di dare anche una spiegazione.

ciao marco
Modificato da nostromo il 25 gennaio 2006 02.11 -

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx
dimenticavo la soluzone più semplice, assegnare ad ogni UserControl l'ID e il gioco è fatto.
:)

se non lo hai già fatto si può ottenere il codice che ti ho postato ieri sera

ciao marco

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx
146 messaggi dal 09 marzo 2005
ciao marco,
grazie per il tuo post ho risolto alla grande il problema.


come hai fatto tu il codice è molto semplice e funzionale perchè quando si aggiunge una nuova voce nel menu con relativo controllo il codice del pageload non deve essere toccato.

se servisse a qualcuno la 'traduzione' in vb del codice di marco.

Note: Ho creato un controllo vuoto per evitare un errore sul primo Load della pagina.

Private Sub Page_Load(...)
Dim contenuto As String = "uc\stat_null.ascx"
If Not Me.ViewState("contenuto") Is Nothing Then
contenuto = Me.ViewState("contenuto")
End If
Dim myControl As Control = Page.LoadControl(contenuto)
myControl.ID = "contenuto"
Me.PlaceHolder1.Controls.Add(myControl)
End Sub

Private Sub LinkButtonStatFonti_Click(...)
Dim c As Control = Me.PlaceHolder1.FindControl("contenuto")
If Not c Is Nothing Then
Me.PlaceHolder1.Controls.Remove(c)
End If
Me.ViewState("contenuto") = "uc\stat_Fonti.ascx"
Dim mycontrol As Control = Page.LoadControl("uc\stat_Fonti.ascx")
mycontrol.ID = "contenuto"
Me.PlaceHolder1.Controls.Add(mycontrol)
End Sub

Private Sub LinkButtonStatOraria_Click(...)
Dim c As Control = Me.PlaceHolder1.FindControl("contenuto")
If Not c Is Nothing Then
Me.PlaceHolder1.Controls.Remove(c)
End If
Me.ViewState("contenuto") = "uc\stat_Orarie.ascx"
Dim mycontrol As Control = Page.LoadControl("uc\stat_Orarie.ascx")
mycontrol.ID = "contenuto"
Me.PlaceHolder1.Controls.Add(mycontrol)
End Sub
contentissimo di esserti stato utilie, ieri sera ho modificato ulteriormente e semplificato il codice, perche stavo indagando alcuni aspetti che non mi erano chiari :)

appena ho metabolizzato posto anche l'atro codice :)

ciao marco

Chi parla senza modestia troverà difficile rendere buone le proprie parole.
Confucio

http://nostromo.spaces.live.com/default.aspx

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.