Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 15

Discussione: Id e clientID

  1. #1
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881

    Id e clientID

    Sono incappato in un problemino.
    Genero via codice una serie di controlli di tipo textbox in questo modo:
    codice:
    for k = 1 to 100
     Dim Tbx = New TextBox()
     Tbx.ID = k & "|" & IDclasse
     Tbx.Text = 0
     Tbx.AutoPostBack = True
     <celladiunatabella>.Controls.Add(Tbx)
     if k >40 then
      AddHandler Tbx.TextChanged, AddressOf Me.TextBox_TextChanged
     end if
    next
    Come si vede, ad alcune di queste celle aggiungo, sempre via codice, un handler per scatenare una funzione quando cambia il contenuto del textbox.
    La funzione fa più o meno quanto segue:
    codice:
     Protected Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
            Dim txtBoxSender As TextBox = sender
            Dim strID As String = txtBoxSender.ID
            Dim IDriga As String = Left(strID, InStr(1, strID, "|", CompareMethod.Text) - 1)
            Dim IDclasse As Integer = CInt(Right(strID, Len(strID) - InStr(1, strID, "|", CompareMethod.Text)))
            Me.titolo_list.Text = "Hai cambiato il valore del controllo in riga" & IDriga & " classe" & IDclasse & " e ci hai messo il valore '" & txtBoxSender.Text & "'"
    ....
    Dim occhioaquesto As TextBox
    occhioaquesto = Me.FindControl(IDriga+5 & "|" & IDclasse+2)
    Il problemino è che il clientId renderizzato è diverso dall'ID che io assegno nel ciclo for ai diversi controlli, quindi il valore strID che io leggo nella funzione non ha "il formato" in cui ho "formattato gli ID nel ciclo e di conseguenza la funzione non estrae IDriga e IDclasse nel modo in cui me l'aspetto ma insieme ad altre parti della stringa strID e, in sintesi, non riesco a trovare il controllo "occhioaquesto"!

    Avendo bisogno di sapere quei due dati che ho indicato nell'ID, ho provato a cercare e ho visto che esiste il modo di far si che il clientID e l'ID affibbiato via codice coincidano, impostando la proprietà ClientIDMode su Static, però credo che questo abbia diverse controindicazioni.
    Sepoffà o nosepoffà? (e anche commesefà? perchè non è una proprietà del controllo ma di non so cosa...)

    Siccome ho visto come renderizza i clientID e mi pare che aggiunga solo una parte di stringa ("contents_") davanti all'ID che ho indicato io, mi chiedo se posso far conto che i clientID siano sempre renderizzati nello stesso modo e modificare la funzione in modo che vada a pescare i valori che mi servono di conseguenza, oppure può succedere che vengano nominati in maniera diversa a seconda di nonsocosa?

    grazie anticipato per le risposte
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  2. #2
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    ma con quale framework ?

    Perche' con questo esempio gli ID rimangono come io li imposto:

    codice:
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            For k As Integer = 1 To 10
                Dim Tbx As New TextBox
                Tbx.ID = k
                Tbx.Text = "prova"
                If k > 5 Then
                    Tbx.AutoPostBack = True
                    AddHandler Tbx.TextChanged, AddressOf Me.TextBox_TextChanged
                End If
                Me.form1.Controls.Add(Tbx)
            Next
        End Sub
    
        Protected Sub TextBox_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs)
            Response.Write(CType(sender, TextBox).ID)
        End Sub

  3. #3
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    ClientIDMode è la proprietà ma è roba per asp.net 4.0 non prima.

    PERO'

    ho visto il codice e devo dire che secondo me sei fuori strada, il tuo problema non è l'id del client, quello ti sarebbe servito se le celle le dovevi modificare lato client (con jquery per esempio). Il problema piuttosto è il findcontrol che non trova il controllo.
    Sei sicuro che la tabella con le celle viene ricreata al postback e tutto esiste cosi come dovrebbe essere al momento in cui provi a recuperare il controllo?
    Poi findcontrol non troverà le textbox incluse in un controllo contenitore. Se la tabella, la riga ed infine la cella non sono contenitori statici devi fare una catena di findcontrol partendo dall'elemento statico. Se per esempio la tabella la crei dinamicamente in un panel noto:
    tabella = Panel1.findcontrol(...
    riga = tabella.findcontrol(...
    cella = riga.find(...
    ...

  4. #4
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    Framework 4
    Confermo che l'ID impostato via codice quando viene renderizzato diventa "contents_" + il mio ID.

    Potrebbe aver ragione rsdpzed:
    l'errore che mi viene restituito è questo
    [NullReferenceException: Riferimento a un oggetto non impostato su un'istanza di oggetto.]
    e si verifica all'interno della funzione quando cerca di usare il riferimento a "occhioaquesto" per pescarne il valore e calcolare una somma

    occhioaquesto = Me.FindControl("contents_" & IDriga & "|" & IDclasse)
    somma = somma + CDbl(occhioaquesto.Text)

    cosa che farebbe presumere che per andare a riferirmi al controllo che voglio indagare io, debba passare per la riga (statica) e la cella (dinamica) che lo contengono...


    Resto comunque col dubbio: il clientID verrà sempre renderizzato come "contents_"+mioID oppure potrebbe variare? Posso fare come nelle due righe di codice sopra o è una burinata?
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  5. #5
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    @djciko
    c'è qualcosa che mi sfugge: ho provato il tuo codice e in effetti il response.write dell'ID del sender scrive l'ID impostato via codice, però se guardi l'html della pagina l'ID del controllo è "contents_..."

    Forse comincio a intravvedere nella nebbia il mio errore: scusatemi sono alle prime armi con asp.net, ho fatto un signor casino... al di là della referenziazione via la catena di findcontrol suggerita da rsdpzed, io ero tuttora convinto che la mia funzione non potesse andare perchè l'ID che cercavo non fosse quello scritto nell'html della pagina, tant'è che l'avevo modificata in modo da lavorare col clientID....

    grazie del supporto e della pazienza, provo a seguire la dritta di rsdpzed e vi faccio sapere
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  6. #6
    Moderatore di ASP.net L'avatar di djciko
    Registrato dal
    Nov 2002
    Messaggi
    6,887
    Originariamente inviato da supermac
    @djciko
    c'è qualcosa che mi sfugge: ho provato il tuo codice e in effetti il response.write dell'ID del sender scrive l'ID impostato via codice, però se guardi l'html della pagina l'ID del controllo è "contents_..."
    Per questo ti ho chiesto il FW. Con il 2.0 continuo a vedere quello che ho impostato io, anche nell'html prodotto.

    <input id="1" etc...

  7. #7
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    Originariamente inviato da djciko
    Per questo ti ho chiesto il FW. Con il 2.0 continuo a vedere quello che ho impostato io, anche nell'html prodotto.
    <input id="1" etc...
    mi sembra una cosa bruttissima!
    rabbrividisco al pensiero di cosa succede a tutti i javascript clientside con delle differenze di comportamento così grandi tra un FW e l'altro...
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  8. #8
    Utente di HTML.it L'avatar di rsdpzed
    Registrato dal
    Aug 2001
    Messaggi
    764
    ciao mac, allora dovresti ricercare il findcontrol partendo dalla riga

    cella = (TableCell)tabella1.riga3.FindControl(
    textBox = (TextBox)cella.FindControl(IDLatoServer)

    Se non funziona debugga step by step e vedi quando hai un null perche a quel punto il problema potrebbe essere che il contenuto che crei dinamicamente non viene ricreato ai postback.

    [Papiro mode=on]
    Ora cerco di spiegare (magari qualcuno potrebbe esssere interessato, anche se non sono un buon "spiegatore") perche il discorso del clientid non centra.
    Quando arriva una richiesta di una pagina aspx al server questo istanzia una classe speciale che fa diverse cose tra cui generare un albero di controlli partendo da quelli dichiarati nella pagina aspx. Dopo di che continua a popolare l'albero dei controlli eseguendo i metodi negli event handler di ogni controllo partendo dalla pagina che è il controllo padre e seguendo un ordine prestabilito (OnInith, OnLoad...), è qui che avviene tutta la logica di presentazione, qui e a questo stadio tu agisci sui controlli lato server e se in questi metodi viene istanziato a run-time un controllo dinamicamente, questo viene semplicemente aggiunto all'albero dei controlli nel posto indicato. Quando questo procedimento ricorsivo è finito hai un albero di controlli in memoria e ognuno di essi deve produrre un output html perciò la classe speciale di cui sopra a questo punto, altro non fa che scorrere l'albero e per ogni nodo richiamare la funzione che renderizza l'html, concatenare le stringhe e restituire la stringa finale come risposta http a quella che inizialmente è stata la chiamata al server.
    Gli id lato client vengono creati da questa funzione di rendering percio quando tu stai ancora agendo sui controlli lato server, per esempio nell'onload di una pagina, il rendering non è ancora avvenuto e non esiste nessun idclient, tutto cio a cui puoi riferirti è il controllo server side che altro non è che una classe istanziata che ha come unico scopo quello di produrre un output html in base a dei parametri che tu puoi governare server side.
    Quindi quello che esattamente succede quando scrivi <TextBox runat="server" ID="TB1" Text="Pippo" /> è creare un oggetto in una collection di tipo IDictionary la cui chiave è ID, e lo istruisci in modo tale che quando verrà renderizzato (tu sai che produrrà un html tag di tipo input) il suo contenuto sarà Pippo. Quell'id identifica l'oggetto nell'albero dei controlli e non rappresenta l'id del tag che esso andra a renderizzare.

    La domanda ora che puo sorgere spontanea è: perche durante il rendering, i controlli generano un idclient se effettivamente a me non serve avere un idclient? (e la cosa potrebbe anche fuorviarmi?)
    Perche serve a lui (asp.net) per esempio a tutto il javascrpt che si occupa della validazione client side e non solo.
    Il motivo per cui asp.net 4 ha deciso di offrire al programmatore uno strumento per controllare la strategia di generazione degli id (cosa che avviene in fase di rendering) è che oggi va molto di moda jquery e ajax e in molte situazioni i programmatori vorrebbero sapere esattamente qual'è la strategia con cui TUTTO l'html, compreso gli id, viene generata (visto che sono tecnologie client side).

    Ora tutta la spegazione di cui sopra potrebbe essere incompleta o contenere qualche inesattezza me è piu o meno quello che accade.

  9. #9
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    mi serve ancora aiuto

    Siccome ne ho davvero tanti in quella tabella, ho fatto questa funzioncina per agganciare il controllo che si trova nella riga IDriga e nella colonna IDClasse (valori che gli passo come argomenti).
    La premessa è che la tabella nasce disegnata nella pagina ma poi, via codebehind, aggiungo delle celle alle righe e ci metto dentro i controlli textbox (non posso usare gridview e altre amenità... non perchè lavori anche io alla rai ma per un altro problema che ci metto di più a spiegarlo che altro)

    codice:
    Private Function trovacontrollo(ByVal riga As Integer, ByVal idclasse As Integer) As TextBox
            Dim row As TableRow, cell As TableCell
            row = Me.FindControl("Tablerow" & riga)
            cell = row.FindControl("cella_" & riga & "|" & idclasse)      '*****
            trovacontrollo = cell.FindControl(riga & "|" & idclasse)
     End Function
    ma si incastra alla riga con gli asterischi.
    L'exception è questa:
    System.NullReferenceException: Riferimento a un oggetto non impostato su un'istanza di oggetto

    E' perchè non trova row o perchè non trova il controllo che dovrebbe valorizzare cell?
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

  10. #10
    Utente di HTML.it L'avatar di supermac
    Registrato dal
    Jun 2001
    Messaggi
    1,881
    OT devo uscire e non potrò fare test sul codice però vi seguo via smartphone (sboronissimo :-) )
    W la Ferari effetrenavenave!
    il computer è un somaro veloce! (neanche tanto ndr)

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.