Non visualizzare un button nella datalist

venerdì 13 maggio 2011 - 18.12

trinity Profilo | Guru

Ragazzi sto utilizzando un datalist per caricare dei commenti che vengono fatti su una notizia..funziona tutto ed in + ho messo un pulsante elimina se l'utente connesso vuole eliminare il suo personale commento...mi rendo però conto che ognuno che logga con la propria password vede tutti i commenti della notizia che sta leggendo e può eliminare sia i proprio commenti che quelli degli altri utenti..
Allora in pratica a me serve che un utente che logga se vede tutti i commenti solo sui suoi appare il pulsante elimina negli altri no...Io nella tabella dei commenti come indici ho sia l'id dell'utente che ha scritto il commento sia l'id della notizia che ovviamente l'id del commento stesso...per ora ecco il codice che utilizzo:

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

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alexmed Profilo | Guru

Prova così:


<asp:Button ID="Button3" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text="Elimina" Visible='<% User.Identity.IsAuthenticated %>' />

Ciao
alexmed

alexmed Profilo | Guru

Scusa ho sbagliato.

Dunque: io l'ho fatto ma su un ListView così
Il Button Elimina:
<asp:LinkButton ID="DeleteLinkButton" ToolTip="Elmina" CommandName="Delete" CommandArgument='<%#Eval("UserName")%>' runat="server" CssClass="..." Height="16px" Width="16px" OnClientClick="return window.confirm('Eliminare Commento?');" />

E da codice per farlo vedere solo a proprietario del commento:

Protected Sub ListView1_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListView1.PreRender

For Each item As ListViewItem In ListView1.Items
Dim b As LinkButton = CType(item.FindControl("DeleteLinkButton"), LinkButton)
If (Not b Is Nothing) Then
If b.CommandArgument = User.Identity.Name Then
b.Visible = True
Else
b.Visible = False
End If
End If
Next

End Sub

Ciao


alexmed

trinity Profilo | Guru

Allora ho eseguito il tuo codice ovviamente adattandolo alle mie esigenze, ti faccio vedere:

in aspx ho scritto così:
<asp:Button ID="Button3" runat="server" CommandArgument='<%# Eval("ID") %>' CommandName="Select" Text="Elimina" OnClientClick="return window.confirm('Eliminare Commento?');"/>

invece in vb ho scritto così:

Private Sub DataList2_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles DataList2.PreRender
For Each item As DataList In DataList2.Items
Dim b As Button = CType(item.FindControl("Button3"), Button)
If (Not b Is Nothing) Then
If b.CommandArgument = User.Identity.Name Then
b.Visible = True
Else
b.Visible = False
End If
End If
Next
End Sub

ma appena eseguo la pagina il debug mi genera un errore del genere:

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

Dove sbaglio?

Ciao e grazie
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alexmed Profilo | Guru

Ciao

For Each item As DataListItem In DataList1.Items
...
Next

Prova.

alexmed

alexmed Profilo | Guru

Resta comunque un problema.
Come CommandArgument passi l'ID dell'utente mentre la funzione che ti ho passato passa l'UserName dell'utente.
Metto a confronto il nome dell'utente Loggato con il nome dell'utente che ha scritto il commento.

Che sistema di autenticazione hai adottato?
Se hai usato quelli messi a dispozizione da VS allora potresti sostituire

If b.CommandArgument = User.Identity.Name Then

con

If b.CommandArgument = Membership.GetUser(User.Identity.Name, False).ProviderUserKey (che restituisce l'ID dell'utente loggato)


alexmed

trinity Profilo | Guru

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

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

ma ora io avevo scritto questo codice sotto vb per eliminare il commento:

Dim conString = ConfigurationManager.ConnectionStrings("liceoConnectionString")
Dim strConnString As String = conString.ConnectionString
Using scope As New TransactionScope()
Using db As New SqlConnection(strConnString)
db.Open()
Using sqlcmd As New SqlCommand("Delcommento", db)
sqlcmd.CommandType = CommandType.StoredProcedure
sqlcmd.Parameters.AddWithValue("@id", SqlDbType.Int).Value = e.CommandArgument
sqlcmd.ExecuteNonQuery()
End Using
End Using
scope.Complete()
End Using[/code]
l'e.CommandArgument deve essere l'id della notizia che ora io non mi porto + sul button perchè mi sono portato l'idutente per gestire la if con il b.CommandArgument, quindi come posso fare?
C'è modo per implementare il CommandArgument così gestire i due id?

Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alexmed Profilo | Guru

Imposta, se non l'hai già fatto, la DataKeyField della DatasList sull'ID del commento.
http://msdn.microsoft.com/it-it/library/system.web.ui.webcontrols.basedatalist.datakeyfield(v=VS.90).aspx
Poi nell'evento "DataList2_ItemCommand" vai ad eseguire la stored attribuendo al parametro "@id" il valore del SelectedValue :

Protected Sub DataList2_ItemCommand(ByVal source As Object, ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs) Handles DataList2.ItemCommand
If e.CommandName = "Select" Then
...
sqlcmd.Parameters.AddWithValue("@id", SqlDbType.Int).Value = DataList2.SelectedValue
...
End If
End Sub

Dovrebbe funzionare.

Ciao



alexmed

Gluck74 Profilo | Guru

Ciao, mi permetto di suggerirti una soluzione che secondo me è più corretta e performate.
Prima di tutto confermo quello che ti ha detto alexmed riguardo il DataKeyNames. Devi impostarlo con il nome del campo ID del commento, solo in questo modo puoi effettuare le cancellazioni.
Come seconda modifica ti proporrei di rinominare il CommandName del pulsante in "Delete" (perché è select se l'operazione è elimina?)
Terza modifica è mettere il pulsante Visible="false"
Questo perché a priori il pulsante non di deve vedere, eccetto che per il proprietario.
Infine, la gestione del pulsante non la farei nel prerender, ma nel ItemDataBound.
Ecco un po di codice:
MembershipUser actualUser; protected void Page_Load(object sender, EventArgs e) { if (User.Identity.IsAuthenticated) { actualUser = Membership.GetUser(); } } protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e) { if (actualUser != null && e.Item.ItemType == ListViewItemType.DataItem) { Button btn = e.Item.FindControl("Button3") as Button; string actualID = actualUser.ProviderUserKey.ToString(); string recordUserID = (e.Item.DataItem as DataRowView)["id"].ToString(); if (actualID == recordUserID) { btn.Visible = true; } } }

Per quanto riguarda la cancellazione, dovrei sapere come hai gestito i dati (SqlDataSource o altro)
Ciao

____________
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

Per alexmed,
ho impostato il datakeyfield sull'id del commento eseguo la datalist.selectedvalue ma non funziona in quanto il valore della selectedvalue è nothing, non viene valorizzato....

ecco il codice in aspx:

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

ed ecco quello in vb:

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


Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

Sinceramente non ho ancora capito se stai usando un DataList o un ListView. In un momento dici di usare il ListView ma nel codice usi l'evento di un DataList.
Comunque, ti do una soluzione per un ListView

Il valore di selectedvalue è nullo perché non esite un item selezionato.
Il comando che stai eseguendo è il delete, quindi devi modificare l'evento, utilizzando ItemDeleting piuttosto che ItemCommand.
I valori dei campi scritti nel DataKeyNames, vengono passati al delegete dell'evento tramite il parametro ListViewDeleteEventArgs.
Modifica in questa maniera:

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

___________________________________
http://blogs.dotnethell.it/glucolo
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

alexmed Profilo | Guru

>Sinceramente non ho ancora capito se stai usando un DataList o un ListView. In un momento dici di usare il ListView ma nel codice usi l'evento di un DataList.

Sono io che ho utilizzato un ListView, trinity ha sempre specificato di usare un DataList.

>Comunque, ti do una soluzione per un ListView

Che però è di un DataList .

La cosa importante è che funzioni.

Ciao

alexmed

trinity Profilo | Guru

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

in vb:

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

Grazie raga
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

se dai retta a me, metti un ListView (nuovo controllo di asp.net 2 che sostituisce e supera il DataList) e in pochi passaggi sei a posto.
Devi solo copiare il mio codice che è fatto per un ListView.

Poi devi assolutamente togliere l'istruzione
For Each item As DataListItem In DataList2.Items
nella
Private Sub DataList2_ItemDataBound
è un errore grave!!!



____________
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

risolto gestendo così:

DataList2.DataKeys(e.Item.ItemIndex)

perchè dovrei togliere for each? e come dovrei scrivere allora scusa
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

Gluck74 Profilo | Guru

ItemDataBound è già un evento che viene lanciato ripetutamente per ogni riga che viene bindata nel controllo.
Ovvero presi i dati dal datasource, esempio 7 record, il controllo deve generare il codice html, ed in particolare il DataList deve generare, per ogni record, il contenuto dell'Itemtemplate.
Come fa? prende il primo record e lo binda in base al codice (ItemTemplate + Bind o Eval), lancia l'evento ItemDataBound, va al prossimo record.
E cos' via.

Quindi il codice che hai scritto dentro il delegate, viene già eseguito 7 volte, uno per ogni record!!!!!!!!!!
Il ForEach dentro è un grosso errore!!!!!!!!!!



_________________________________________________
http://blogs.dotnethell.it/glucolo
Ricordati di utilizzare il tasto "Accetta" se i nostri consigli ti sono serviti a risolvere il problema.
È il modo per ringraziare chi ti ha aiutato.

trinity Profilo | Guru

OK thx della info
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

trinity Profilo | Guru

Senti ho fatto come hai detto te ho tolto il for each nell'evento ItemDataBound, ma non mi funziona + perchè ho dovuto dichiarare la variabile item in un'altra maniera e mi dice che l'oggetto di riferimento non è esistente, ti posto il codice:

La parte remmata era il codice vecchio così puoi vedere anche quello perchè mi riporta sempre il valore dell'iddocente della prima riga del datalist:

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

e cmq sto ricontrollando che sia con il for each che senza il codice all'interno della b.commandargument non viene mai eseguito.... ti posto anche il codice aspx

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


se metto il codice nel prerender con una modifica e lasciano il for each funziona....

Ciao
Cirillo Fabio
www.wondernet.biz
fabio@wondernet.biz
http://blogs.dotnethell.it/fabiocirillo/
http://wnetsoftware.blogspot.com

alexmed Profilo | Guru

Ciao,
se non hai ancora risolto ...
Prima di tutto, come indicato da Gluck74, cambierei il DataList con ListView, ricordantoti di indicare il DataKeyNames, senza grossi problemi perchè mantieni lo stesso ItemTemplate .
Poi, sempre come indicato da Gluck74 per visualizzare o no il DeleteButton nell'evento ListView1_ItemDataBound metti:

Dim b As LinkButton = CType(e.Item.FindControl("DeleteLinkButton"), LinkButton)
If (Not b Is Nothing) Then
If b.CommandArgument = User.Identity.Name Then
b.Visible = True
Else
b.Visible = False
End If
End If

e nella pagina ASPX

<asp:LinkButton ID="DeleteLinkButton" ToolTip="Elmina" CommandName="Delete" CommandArgument='<%#Eval("UserName")%>' runat="server" Height="16px" Width="16px" OnClientClick="return window.confirm('Eliminare Commento?');" />

Infine resta la procedura per l'eliminazione del commento: se usi un SqlDataSource basta assegnarli la stored al DeleteCommand.

SqlDataSource.DeleteCommand = "nome_della_stored"
SqlDataSource.DeleteCommandType = "StoredProcedure"

Ciao



alexmed
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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5