Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    [2.0-VB.NET]creazione controlli dinamici in wizard

    Ciao, sto realizzando una procedura interna ed ho problemi proprio nella parte più importante: un wizard per creare un certo tipo di documenti.

    Nella prima pagina del wizard l'utente imposta le opzioni con cui verrà generato il documento:
    screenShot della pagina 1

    Nella seconda pagina i controlli vengono creati dinamicamente in base alle opzioni scelte nella prima, questo per permettere all'utente di sovrascrivere le voci proposte dalla procedura:
    screenShot della pagina 2
    (le righe in azzurrino coi checkBox spuntati sono quelle che l'utente stà personalizzando)

    Nella pagina finale (la terza) dovrei memorizzare il tutto ma mi sono accorto che asp.net non mi vede i checkox e le textbox che ho aggiunto dinamicamente

    Questa è la funzioncina rozza con cui genero una riga per la personalizzazione:
    codice:
        Protected Function CrateCustomizationRow(ByVal wich As String, ByVal Qt As String, ByVal PN As String, ByVal description As String) As String
            ' Crea riga di personalizzazione
            Dim cRow As String
            cRow += "    <tr id='tr" & wich & "'>"
            cRow += "        <td style='width: 21px'>"
            cRow += "           <input type='checkbox' name='chkCustomize" & wich & "' onclick='switchCustomizationRow(&quot;" & wich & "&quot;)'>"
            cRow += "        </td>"
            cRow += "        <td style='width: 24px' align='center'>"
            cRow += "           <div id='div" & wich & "LblQt'>" & Qt & "</div>"
            cRow += "           <div id='div" & wich & "TBQt' style='display = none'><input type='textbox' name='TBQt" & wich & "' value='" & Qt & "' size='2' class='userInput'></div>"
            cRow += "        </td>"
            cRow += "        <td style='width: 79px'>"
            cRow += "           <div id='div" & wich & "LblPn'>" & PN & "</div>"
            cRow += "           <div id='div" & wich & "TBPn' style='display = none'><input type='textbox' name='TBPn" & wich & "' value='" & PN & "' size='13' class='userInput'></div>"
            cRow += "        </td>"
            cRow += "        <td style='width: 479px'>"
            cRow += "           <div id='div" & wich & "LblDescription'>" & description & "</div>"
            cRow += "           <div id='div" & wich & "TBDescription' style='display = none'><input type='textbox' name='TBDescription" & wich & "' value='" & description & "' size='93' class='userInput'></div>"
            cRow += "        </td>"
            cRow += "        <td style='width: 18px' align='center'>"
            cRow += "           <div id='div" & wich & "LnkSelectorInactive'>[img]images/search-blue-off.gif[/img]</div>"
            cRow += "           <div id='div" & wich & "LnkSelector' style='display = none'>[img]images/search-blue.gif[/img]</div>"
            cRow += "        </td>"
            cRow += "    </tr>"
            Return cRow
        End Function 'Crea riga di personalizzazione
    Credendo che il problema fosse che creo controlli 'html standard' invece di controlli asp.net ho provato a seguire un tutorial in cui si consigliava di creare i controlli in questa maniera:
    codice:
        Dim codeToParse As String = "<asp:Label runat='server' id='lblTest" & wich & "' Text='Sono la lblTest" & wich & "' />"
        Dim testControl As Control = ParseControl(codeToParse)
        TestPlaceHolder.Controls.Add(testControl)
    Il controllo viene creato (a video lo vedo) ma se provo a leggerne il valore mi dice ancora che non esiste!

    Messaggio di errore del compilatore: BC30451: Nome 'lblTestMotor ' non dichiarato.
    (dove 'Motor' è un suffisso che appendo io dinamicamente in fase di creazione del controllo)


    Riassumendo: come si crea dinamicamente un controllo che prenda il nome (ID) da una variabile in modo che se ne possa, in seguito, leggerne il valore inserito da un utente?

    Grazie e scusate, sono migrato ad asp.net da pochissimo tempo.

  2. #2
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    Devi aggiungere (AddHandler) un gestore:

    VB:
    codice:
    Partial Class Default
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim variabile As String = "IDCbox"
            Dim myCB As New CheckBox
            myCB.ID = variabile
            myCB.AutoPostBack = True
    
            'Aggiungo un gestore per 'CheckedChanged'
            AddHandler myCB.CheckedChanged, AddressOf GestoreClickCB
    
            ph.Controls.Add(myCB)
        End Sub
    
        Private Sub GestoreClickCB(ByVal sender As Object, ByVal e As EventArgs)
            Response.Write("hai cambiato la checkbox")
        End Sub
    End Class
    ps: 'ph' è un <asplaceholder> nella pagina default.aspx.

  3. #3
    Originariamente inviato da djciko
    Devi aggiungere (AddHandler) un gestore:

    VB:
    codice:
    Partial Class Default
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Dim variabile As String = "IDCbox"
            Dim myCB As New CheckBox
            myCB.ID = variabile
            myCB.AutoPostBack = True
    
            'Aggiungo un gestore per 'CheckedChanged'
            AddHandler myCB.CheckedChanged, AddressOf GestoreClickCB
    
            ph.Controls.Add(myCB)
        End Sub
    
        Private Sub GestoreClickCB(ByVal sender As Object, ByVal e As EventArgs)
            Response.Write("hai cambiato la checkbox")
        End Sub
    End Class
    ps: 'ph' è un <asplaceholder> nella pagina default.aspx.

    Hai messo il codice in Page_Load solo per farmi un'esempio oppure posso creare controlli solo in quel momento?
    Io ho bisogno di crearli quando il wizard passa dalla pagina 1 alla pagina 2, spero che sia la stessa cosa crearli da una funzione associata a quell'evento ...anche se la logica suggerirebbe il contrario.

    Il risultato che devo ottenere io è piuttosto incasinato, spero di cavarmela gestendo le cose tramite AddHandler ..visto che l'handler dovrà gestire anche gli altri controlli dinamici facenti parte della stessa riga

    ...cmq adesso mi fumo una sigaretta e poi riparto di slancio a fare prove con i tuoi consigli!

    Per adesso Grazie!, ti faccio sapere

  4. #4
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    Originariamente inviato da BSOD
    Hai messo il codice in Page_Load solo per farmi un'esempio oppure posso creare controlli solo in quel momento?
    Io ho bisogno di crearli quando il wizard passa dalla pagina 1 alla pagina 2, spero che sia la stessa cosa crearli da una funzione associata a quell'evento ...anche se la logica suggerirebbe il contrario.

    Il risultato che devo ottenere io è piuttosto incasinato, spero di cavarmela gestendo le cose tramite AddHandler ..visto che l'handler dovrà gestire anche gli altri controlli dinamici facenti parte della stessa riga

    ...cmq adesso mi fumo una sigaretta e poi riparto di slancio a fare prove con i tuoi consigli!

    Per adesso Grazie!, ti faccio sapere
    Io ho creato una CheckBox e l'ho aggiunta ad un PlaceHolder. Puoi farlo in qualsiasi punto del codice. Creati i gestori giusti e lascia stare il metodo che hai postato sopra (cioè scrivere il tag del controllo tramite una stringa).

    E' più facile creare un'istanza del controllo, darle i giusti valori e poi aggiungerla ad un contenitore (placeholder). Fai sapere il risultato,

  5. #5
    Come cantava Zucchero: "lo sai, fratello, siamo nella mer..."

    Ho fumato la sigaretta e ho fatto le seguenti prove:
    1) Ho inserito il tuo codice nella funzione dove mi servirebbe che stesse (CreateCustomizationRow) ma mi diceva ancora che l'oggetto non è stato dichiarato.
    2)Stesso codice in Page_Load e, ti sembrerà incredibile, ma non me lo vede lo stesso

    Il codice:
    codice:
    Dim nomeChkBox As String = "chkCustomize" & "Motor" 'simulo l'aggiunta di una variabile
    Dim chkSwitch As New CheckBox
    chkSwitch.ID = nomeChkBox
    chkSwitch.AutoPostBack = False
    TestPlaceHolder.Controls.Add(chkSwitch)
    Il controllo mi viene creato sempre correttamente e vedo, a video, il mio bel checkBox a cui, per ora, non ho associato nessun handler.
    Ho impostato l'autopostback a false perchè altrimenti quando lo cliccavo spariva e non veniva più ricreato (probabilmente era la prova fuori dal page_load)

    In pratica il controllo esiste solo a video, il codice ne ignora completamente l'esistenza
    Se provo a fare un: testLabel.Text = chkCustomizeMotor.Checked()
    ...continua a dirmi: BC30451: Nome 'chkCustomizeMotor' non dichiarato.

    qualche idea? Non credo sia per il wizard e nemmeno per un piccolo updatePanel presente solo intorno a due campi nella pagina 1 dello stesso.
    Oppure il fatto è che , semplicemente, non posso leggerne il valore ma solo associarvi un handler e gestire tutto da quello? Se così fosse non potrò mai recuperare il valore delle textBox di personalizzazione per scriverli nel db ...ma spero proprio di sbagliarmi.

    Mi sai rimettere sulla strada giusta?
    In asp 3.0 sapevo come farlo ma son troppo acerbo in .net per capire cosa sta succedendo


    [EDIT]
    Ho fatto un'altra prova, ho aggiunto un gestore di eventi che mi scrivesse in una label l'ID del checkBox cliccato e ho quindi dovuto settare l'autopostback a true.
    Il risultato è che non posso controllare se funziona perchè, come avevo anticipato, il checkBox con l'autopostback sparisce appena lo clicco e, forse proprio per quello, la label di debug mi resta col testo di default uguale a 'label'
    codice:
        Private Sub GestoreClickCB(ByVal sender As Object, ByVal e As EventArgs)
            labelCB.Text += sender.ID & "
    "
        End Sub
    [/EDIT]

  6. #6
    Aggiornamento:

    Ho provato ancora, nel Page_Load funziona perfettamente e riesco a recuperare i valori dei controlli che creo dinamicamente ...grazie ancora DjCiko!

    codice:
        Sub Page_load(ByVal sender As Object, ByVal e As EventArgs)
            Dim nomeChkBox As String = "chkCustomize" & "Motor" 'simulo l'aggiunta di una variabile
            Dim chkSwitch As New CheckBox
            chkSwitch.ID = nomeChkBox
            chkSwitch.AutoPostBack = True
            AddHandler chkSwitch.CheckedChanged, AddressOf GestoreClickCB
            TestPlaceHolder.Controls.Add(chkSwitch)
        End Sub 
    
        Private Sub GestoreClickCB(ByVal sender As Object, ByVal e As EventArgs)
            labelCB.Text += sender.ID & "
    "
        End Sub
    Purtroppo però in un'altro punto del codice non funziona, fuori dal page_load i controlli vengono creati ma non possono più essere letti da asp.net ...provare a leggerne il valore restituisce l'errore di oggetto non dichiarato.

    A me server proprio questo, creare controlli fuori dal page_load ...quando passo alla seconda pagina del wizard.

    C'è qualche scappatoia al mio problema?
    Giuro che se scopro che non è possibile fare una cosa così mi do all'allevamento di vermi

  7. #7
    Soluzione:

    La tecnica suggeritami da DjCiko va benissimo ed è risolutiva ...è il mio cervello a fare acqua oggi

    In pratica è vero che si è limitati a creare controlli nel page_load se si vuole poi leggerne i valori (almeno stando ale mie prove) ma è falso che questo pregiudichi il comportamento di un wizard che deve creare controlli ad un determinato cambio di pagina.

    La soluzione semplicissima è:
    codice:
        Sub Page_load(ByVal sender As Object, ByVal e As EventArgs)
           If theWizard.ActiveStepIndex = 1    'pagina in cui verranno creati i controlli
                'creo i controlli con la tecnica di djciko
           End If
        End Sub
    Dovrò sbattermi parecchio per cambiare un po di cosette ma mi si è riaccesa la speranza

    Buona serata al guru

  8. #8
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    Originariamente inviato da BSOD
    Soluzione:

    La tecnica suggeritami da DjCiko va benissimo ed è risolutiva ...è il mio cervello a fare acqua oggi

    In pratica è vero che si è limitati a creare controlli nel page_load se si vuole poi leggerne i valori (almeno stando ale mie prove) ma è falso che questo pregiudichi il comportamento di un wizard che deve creare controlli ad un determinato cambio di pagina.

    La soluzione semplicissima è:
    codice:
        Sub Page_load(ByVal sender As Object, ByVal e As EventArgs)
           If theWizard.ActiveStepIndex = 1    'pagina in cui verranno creati i controlli
                'creo i controlli con la tecnica di djciko
           End If
        End Sub
    Dovrò sbattermi parecchio per cambiare un po di cosette ma mi si è riaccesa la speranza

    Buona serata al guru
    Prego, ma comunque non capisco perchè sei costretto a crearli dinamicamente, questi controlli. Non sai quanti ne devi creare ?

  9. #9
    Esattamente, NON so quanti campi dovrò creare.
    Il numero dei campi dipende, soprattutto, dal modello di macchina che si sceglie nella pagina 1 , dai suoi settaggi di funzionamento e dagli accessori di cui si vuole corredarla (vedi screenShot1).

    Alcune configurazioni avranno addirittura più di 50 'righe' di output che l'utente deve poter personalizzare nella pagina2, altre, più semplici, potrebbero averne solamente una decina ...ma il tipo di righe e il loro numero è un'incognita e deve essere gestito dinamicamente.
    [EDIT]
    In pratica non dipendono dal numero di campi presenti nella pagina1 ma da COME vengono compilati . Compilando i 3 campi più importanti (modello, ventola e frequenza) si possono già ottenere svariati risultati per quanto riguarda il numero di componenti che poi appariranno nella pagina2.
    Spero di essermi spiegato bene
    [/EDIT]

    Comunque ho fatto altre prove e sono quasi sicuro di potermela cavare con il metodo che ho descritto come soluzione e, grazie a te, quei controlli adesso mi mantengono anche il viewstate ...cosa che i miei controllacci in html non potevano fare da soli.

    Come ho detto dovrò lavorarci parecchio per riadattare il tutto ma adesso sono sicuro di avere tutto quello che mi serve per portare a termine la sezione.

    Se sei interessato a quello che sto facendo ti posso zippare e spedire il progetto spogliato delle altre parti, fammi sapere ...lo faccio volentieri a mo' di gratitudine

  10. #10
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    Ti direi una bugia se dicessi che ho tempo di spulciarlo...

    Comunque, ti consiglio di generare gli ID dei controlli con una logica ben precisa.
    Tipo "CTR_TXT" + ViewState("controllidinamici") [tenendo il conto di quanti ne generi], per poi rigenerarli (ricreare lo stato, cioè) esattamente con gli stessi ID.

    Questo ti permette anche di cercare il controllo in un altro punto del codice (sempre generandoli fra i postback nel pageload) se ne hai bisogno, così:
    codice:
            Dim CB As CheckBox = DirectCast(Page.FindControl("CTR_CB7"), CheckBox)

    Ci saranno anche altri modi per fare tutto ciò, cmq. CustomControl e cosi' via, ma si complica.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.