yoyo041080
Messages postés18Date d'inscriptionmercredi 18 mai 2005StatutMembreDernière intervention10 septembre 2007
-
11 juin 2007 à 09:26
alex -
14 janv. 2014 à 12:19
Bonjour,
J'ai un GridView dans lequel j'ai un Template field contenant un checkbox sur lequel agiront mes utilisateurs pour sélectionner ou non la donnée représentée par la ligne du GridView
<asp:CheckBox
ID ="ckbFonction"
runat= "server"
/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Je souhaite lors de la validation parcourir l'intégralité des pages affichées par ma GridView afin de récupérer ou non la sélection de ces CheckBox
Pour cela, je fais :
For
Each myRow As GridViewRow In gvSeuils.Rows
If
CType(myRow.Cells(7).Controls(1), CheckBox).Checked
Then seuilSelectionnee =
True
Exit
For
End
If
Next
Le souci, c'est que gvSeuils.Rows ne renvoie que le nombre de lignes affichées (10 pour moi) par la pagination, je ne parcours donc que les données de la page courante affichée
Je n'arrive pas à mettre la main sur la nom de la propriété permettant de parcourir intégralement toutes les lignes.
yoyo041080
Messages postés18Date d'inscriptionmercredi 18 mai 2005StatutMembreDernière intervention10 septembre 2007 11 juin 2007 à 16:31
Merci de ta réponse
Autant pour moi, je n'ai pas précisé que j'avais testé le parcours avec changement de page :
nbPage = gvSeuils.PageCount - 1
For indexPage
As
Integer = 0
To nbPage gvSeuils.PageIndex = indexPage
For
Each myRow
As GridViewRow
In gvSeuils.Rows
If
CType(myRow.Cells(7).Controls(1), CheckBox).Checked
Then ' traitement
End
If
Next indexPage += 1
Next
Cette solution ne fonctionne malheureusement pas Il ne tiens pas compte du changement de page et renvoie les données de la page courante...
D'ailleurs, dans la MSDN, il est écrit :
AllowPaging property to true), use the PageIndex property to determine the index of the currently displayed page. You can also use this property to programmatically change the displayed page.
Il n'est pas précisé que ça permet de parcourir l'intégralité du GridView "programmatically"
yoyo041080
Messages postés18Date d'inscriptionmercredi 18 mai 2005StatutMembreDernière intervention10 septembre 2007 11 juin 2007 à 17:22
Merci, mais comme je l'explique dans mon premier message, l'idée est :
1) de proposer une liste d'environ 250 éléments affichés par page de 10 éléments
2) je laisse les utilisateurs sélectionner dans ces 25 pages les éléments qu'ils veulent
3) c'est lors de la validation de la page que je veux parcourir mon GridView pour récupérer la sélection
Donc, RowDataBound ne me permet pas de faire ceci
Je ne dois pas être le seul à vouloir faire cette manipulation élémentaire dans une IHM
yoyo041080
Messages postés18Date d'inscriptionmercredi 18 mai 2005StatutMembreDernière intervention10 septembre 2007 11 juin 2007 à 17:48
Je voudrais récupéré mes données à la validation définitive de ma page, pas sur un PostBack de changement de page d'un GridView.
Pourquoi ? Pour récupérer en une seule fois la liste des données sélectionnées.
Je comprends ce que tu me proposes. Le problème, c'est que comme on peut revenir plusieurs fois sur la même page pour cocher et décocher des éléments, ça oblige à faire des recherche dans une collection pour savoir si l'élément existe ou non dedans. Je te laisse imaginer les performances... (ma liste minimale est de 250 éléments)
Enfin, il me semble que RowDataBound est déclenché au chargement de la page, pas à sa validation :
Validation de la page => Load de la page suite au post back => chargement des données de la gridview => rowdatabound pour chaque ligne
yoyo041080
Messages postés18Date d'inscriptionmercredi 18 mai 2005StatutMembreDernière intervention10 septembre 2007 11 juin 2007 à 17:51
J'ajoute une pécision à ma pensée du dessus
Si l'événement RowDataBound est bien au chargement de la page, suite au post-back, les données modifiées ne sont plus visibles dans le GridView car on a changé de page
cs_drahcir
Messages postés745Date d'inscriptionmardi 30 novembre 2004StatutMembreDernière intervention15 septembre 20094 11 juin 2007 à 18:00
C'est bien ça, il y a un post back à chaque changement de page (il me semble en tout cas).
Regarde si tu n'as pas un moyen de ne pas générer de post back (je me demande s'il y a pas une propriété...)
Sinon pour rester dans le RowDataBound, tu peux toujours ajouter des lignes cochées dans une collection et tu feras ton traitement à la validation.
Le problème, c'est qu'à chaque fois ça t'oblige à tester qu'elles ne sont pas déjà résente dans ta collection avant de les ajouter...
Donc en terme de perf, c'est peut-être pas ce qu'il y a de mieux!!!
Si j'ai une autre idée, je t'en fais part... et si tu trouves, postes ta réponses c'est toujours intéressant
cs_Nurgle
Messages postés1642Date d'inscriptionsamedi 6 novembre 2004StatutMembreDernière intervention28 avril 20114 11 juin 2007 à 22:44
Salut,
Attention, il faut bien comprendre que ASP.NET ne stocke rien entre deux Postback ! Et comme un changement de page du gridview nécessite un aller/retour serveur (donc un PostBack) pour charger les données suivantes, tu ne peux faire ta validation que pour chaque page, séparément des autres.
Une solution "simple" consisterait à stocker (en Session) un tableau contenant les IDs (ou ce que tu veux) identifiant les éléments "sélectionnés" sur l'ensemble des pages.
A chaque changement de page tu fais un .Add() pour chaque CheckBox cochée et un .Remove() sur chaque décochée (pas grave si l'élément n'existe pas, le Remove ne lève pas d'exception pour ça ; et de plus ça évite de vérifier si la collection ne contient pas déjà l'élément lors du Add() )
Pour l'évènement auquel il faut s'abonner, je dirais je PageIndexChanging, qui se produit au changement de page mais avant que le GridView ne fasse la requête pour récupérer les données suivantes (il contient donc toujours les anciennes données, et donc aussi les CheckBox cochées ou pas).
Et vu qu'on peut revenir plusieurs fois sur la même page, il faut que tes CheckBox conservent l'état qu'elles avaient, donc, dans le RowDataBound cette fois, là tu vas devoir faire une boucle sur le tableau pour re-remplir les CheckBox...
Ensuite à la validation finale (un click sur un bouton, ou ce que tu veux), après avoir également parcouru les lignes de la dernière page (ne pas l'oublier celle là, il n'y aura pas de PageIndexChanging de levé vu que tu ne changes pas de page ) tu sais quelles ont été les données sélectionnées et tu peux faire ce que tu veux avec...
(il y peut être plus simple mais je vois pas...)
Niveau perf, ce qui compte c'est que le nombre d'élements sélectionnés ne soit pas trop important, genre n'atteigne pas les 1000...
le nombre total d'éléments, ou le nombre par page, sont sans importance...
cs_Nurgle
Messages postés1642Date d'inscriptionsamedi 6 novembre 2004StatutMembreDernière intervention28 avril 20114 11 juin 2007 à 22:47
Un autre petit truc pour améliorer les perfs : stocke dans une autre variable Session un tableau contenant les numéros des pages déjà visitées. ça coute rien (un petit tableau d'int) mais ça te permet, dans le RowDataBound, de ne pas parcourir la collection pour re-remplir les CheckBox si la page n'a jamais été visité...
Avec peu de données ça changera pas grand chose, mais dès que tu auras pas mal d'éléments, ça évitera pleins de parcours inutiles de la collection...
ça fait quand même beaucoup de bordel pour pas grand chose... décidement, il doit y avoir un truc qui m'est passé sous le nez...
J'avais en attendant mis en place la solution que tu proposes pour pouvoir avancer (hormis la mémorisation des pages visitées), j'avais l'impression que c'était du bricolage, mais je vois qu'apparemment, il n'y aurait pas d'autre solution...
Je ne coche pas ta réponse comme "Acceptée" car ce n'est pas la réponse exacte à ma question, puisque l'on ne parcourt pas de A à Z le GridView, mais par page avec des sauvegardes intermédiaires...
Je post mon code associé à ta réponse en dessous, si ça peut aider pour quelqu'un d'autres...
Set(
ByVal value
As Profil) Session(URL_PAGE_PROFIL & CLE_OBJET) = value
End
Set
End
Property=> mon objet de type Profil contient une collection nommée "Seuils" fournissant les méthodes "Add", "Remove" et "Contains"
=> ce sont des objets de type "Seuil" que j'affiche dans mon GridView
' la gestion de l'événement "PageIndexChanging"
Protected
Sub gvSeuils_PageIndexChanging(
ByVal sender
As
Object,
ByVal e
As System.Web.UI.WebControls.GridViewPageEventArgs)
Handles gvSeuils.PageIndexChanging
' ici, le changement de page n'a pas encore eu lieu
EnregistreDonneesGridViewGvSeuils()
' fonction de mon API qui gére le tri et la pagination de mon GridView
GridViewHelper.HandlePageIndexChanging(gvSeuils, ViewState, e)
End
Sub
' la gestion de l'événement "RowDataBound"
Protected
Sub gvSeuils_RowDataBound(ByVal sender AsObject, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvSeuils.RowDataBound
Dim myId
As
Integer
Dim mySeuil
As Seuil
If
Not e.Row.FindControl(
"ckbFonction")
Is
Nothing
Then
' l'id est en premiŠre position
If e.Row.Cells(0).Text <>
""Then myId Integer.Parse(e.Row.Cells(0).Text) mySeuil Seuil.Load(myId)
For
Each myRow
As GridViewRow
In gvSeuils.Rows ' je lis l'identifiant unique de ma donnée en début de ligne de mon GridView
myId =
CInt(myRow.Cells(0).Text)
' j'utilise NHibernate, je charge mon objet complet à partir de son Id
mySeuil = Seuil.Load(myId)
If
Not mySeuil
Is
Nothing
Then
If
CType(myRow.Cells(7).Controls(1), CheckBox).Checked
Then
' si checkbox coché, j'ajoute à la collection
Me.ObjetCourant.Seuils.Add(mySeuil)
Else
' si checkbox non coché, je supprime de la collection
Me.ObjetCourant.Seuils.Remove(mySeuil)
End
If
End
If
Next
End
Sub
Remarque : mon objet de type "Seuil" redéfini la méthode "Equals" pour que les fonctions "Add", "Remove" et "Contains" puissent fonctionner correctement
Enfin, lors de la validation de la page, j'appelle une nouvelle fois la fonction EnregistreDonneesGridViewGvSeuils pour mémoriser la sélection des CheckBox de la page courante.
cs_obel
Messages postés34Date d'inscriptionlundi 4 août 2003StatutMembreDernière intervention17 juin 2008 12 juin 2007 à 10:06
il y a qq1 qui peux regarder mes posts j'ai besoin d'aide pour une dropdown list imbriqué dans un repeater avec un where 'xxxx' dans la requete et je sèche grave !!!
Bonjour
Le sujet date beaucoup mais je n'ai pas trouvé de sujet plus recent sur le même problème
Je poste une petite solution très simple mais à confirmer par quelqu'un qui s'y connait un peu mieux que moi :
dans le codebehind
- mettre le parametre de la gridview allowpagging=false avant de parcourir la gridview
- faire un databind de la gridview
maintenant le foreach pourra parcourir l'ensemble des données
Après le for each(je ne sais pas si c'est necessaire ):
-remettre allowpagging=true
-faire un autre databind
Testé et ça fonctionne impec'.
Là où j'ai un doute, c'est que je ne sais pas si la fonction databind lie les donnés déjà chargées (idéalement c'est ce que je veux)
ou si elle fait appel à une requete bdd (et là c'est tout de suite moins interressant si on doit faire plusieurs fois une requête)
un avis ?
note : dans mon exemple, j'ai une griedview remplie par un ObjectDataSource qui fait appel à une requête SQL.
Je suis en C# mais je suppose que la partie .aspx est identique quel que soit le language
EDIT : un collègue m'a soufflé que dans mon cas je pouvais tout simplement parcourir mon datasource, effectivement c'est bien plus efficace