Précédent   Forum du club des développeurs et IT Pro > Dotnet > Développement Web avec .NET > ASP.NET
ASP.NET ASP.NET -Forum d'entraide sur le Développement Web en ASP.NET. Avant de poster -> FAQ ASP.NET, Articles ASP.NET
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 22/12/2012, 00h55   #1
youtpout978
Membre Expert
 
Homme John Doe
Développeur .NET
Inscription : novembre 2010
Messages : 902
Détails du profil
Informations personnelles :
Nom : Homme John Doe
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : novembre 2010
Messages : 902
Points : 1 439
Points : 1 439
Par défaut Factoriser code de tri gridview

Bonjour,
j'ai un gridview bindé à une liste:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 
        <asp:GridView ID="GridViewGS" runat="server" BackColor="White" BorderColor="Black"
            AutoGenerateColumns="False" AllowSorting="True" BorderStyle="None" BorderWidth="1px"
            CellPadding="3" OnSorting="GridViewGS_Sorting">
            <Columns>
                <asp:BoundField DataField="Classement" HeaderText="Classement &#9660;" SortExpression="Classement">
                    <HeaderStyle Wrap="False" />
                    <ItemStyle HorizontalAlign="Center" />
                </asp:BoundField>
                <asp:TemplateField HeaderText="Nom &#9660;" SortExpression="Nom">
                    <ItemTemplate>
                        <asp:Image ID="ImgMVP" runat="server" ImageUrl="~/Images/MVP.png" Visible='<%# Eval("EstMVP")%>' />
                        <asp:Label ID="LblNom" runat="server" Text='<%# Bind("Nom")%>' ForeColor='<%# Eval("CouleurDefenseur") %>' />
                    </ItemTemplate>
                    <HeaderStyle Wrap="False" />
                    <ItemStyle Wrap="False" />
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Guilde &#9660;" SortExpression="NomGuilde">
                    <ItemTemplate>
                        <asp:Image ID="ImgGuilde" runat="server" ImageUrl="~/Images/Couronne.png" Visible='<%# Eval("ALaCouronne") %>' />
                        <asp:Label ID="LblGuilde" runat="server" Text='<%# Bind("NomGuilde")%>' />
                    </ItemTemplate>
                    <HeaderStyle Wrap="False" />
                    <ItemStyle Wrap="False" />
                </asp:TemplateField>
                <asp:BoundField DataField="Points" HeaderText="Points &#9660;" SortExpression="Points">
                    <ItemStyle HorizontalAlign="Center" />
                    <HeaderStyle Wrap="False" />
                </asp:BoundField>
                <asp:BoundField DataField="NbFrags" HeaderText="Frags &#9660;" SortExpression="NbFrags">
                    <ItemStyle HorizontalAlign="Center" />
                    <HeaderStyle Wrap="False" />
                </asp:BoundField>
                <asp:TemplateField HeaderText="Victimes">
                    <ItemTemplate>
                        <asp:Label ID="LblVictimes" runat="server" Text='<%# Eval("HtmlVictimes") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:TemplateField HeaderText="Bourreaux">
                    <ItemTemplate>
                        <asp:Label ID="LblBourreaux" runat="server" Text='<%# Eval("HtmlBourreaux") %>' />
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
            <FooterStyle BackColor="White" ForeColor="#000066" />
            <HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
            <SelectedRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
            <SortedAscendingCellStyle BackColor="#F1F1F1" />
            <SortedAscendingHeaderStyle BackColor="#007DBB" />
            <SortedDescendingCellStyle BackColor="#CAC9C9" />
            <SortedDescendingHeaderStyle BackColor="#00547E" />
        </asp:GridView>
dont j'ai implémenté une méthode de tri

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
 
    protected void GridViewGS_Sorting(object sender, GridViewSortEventArgs e)
        {
            try
            {
                List<Joueur> joueurs = ViewState["joueurs"] as List<Joueur>;
                if (joueurs == null)
                    return;
 
 
                string sortExpression = e.SortExpression;
                string ancienTri = this.SortExpression;
 
                //si tri sur la même colonne
                if (this.SortExpression == e.SortExpression)
                {
                    this.SortDirection = this.SortDirection == SortDirection.Ascending ?
                           SortDirection.Descending : SortDirection.Ascending;
                }
                else  //tri sur une nouvelle colonne: mettre Ascending
                {
                    this.SortExpression = e.SortExpression;
                    this.SortDirection = SortDirection.Ascending;
                }
 
 
                //int cell = 0;
 
                //if (GridViewGS.Rows.Count > 0 && GridViewGS.Rows[0].Cells.Count > 0)
                //{
                //    int.TryParse(GridViewGS.Rows[0].Cells[0].Text, out cell);
                //}
 
 
                switch (sortExpression)
                {
                    case "Nom": if (SortDirection == SortDirection.Ascending)
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom);
                        else
                            GridViewGS.DataSource = joueurs.OrderByDescending(j => j.Nom);
 
                        break;
 
                    case "Classement": if (!EstTrieeParClassement())
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderBy(j => j.Classement);
                        else
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.Classement);
 
                        break;
 
                    case "NomGuilde": if (SortDirection == SortDirection.Ascending)
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderBy(j => j.NomGuilde);
                        else
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.NomGuilde);
 
                        break;
 
                    case "Points": if (SortDirection == SortDirection.Ascending)
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderBy(j => j.Points);
                        else
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.Points);
 
                        break;
 
                    case "NbFrags": if (SortDirection == SortDirection.Ascending)
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderBy(j => j.NbFrags);
                        else
                            GridViewGS.DataSource = joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.NbFrags);
 
                        break;
                    default:
                        break;
                }
 
                GridViewGS.DataBind();
            }
            catch (Exception ex)
            {
                LblErreur.Text = ex.Message;
            }
 
        }
 
  private bool EstTrieeParClassement()
        {
 
            if (GridViewGS.Rows.Count > 1 && GridViewGS.Rows[0].Cells.Count > 1)
            {
                for (int i = 1; i < GridViewGS.Rows.Count; i++)
                {
                    int cellActuel = int.Parse(GridViewGS.Rows[i].Cells[0].Text);
                    int cellPrecedente = int.Parse(GridViewGS.Rows[i - 1].Cells[0].Text);
 
                    if (cellActuel < cellPrecedente)
                    {
                        return false;
                    }
                    else if (cellActuel == cellPrecedente)
                    {
                        string nomActuel = ((Label)GridViewGS.Rows[i].FindControl("LblNom")).Text;
                        string nomprecedent = ((Label)GridViewGS.Rows[i - 1].FindControl("LblNom")).Text;
                        int t = nomActuel.CompareTo(nomprecedent);
                        if (nomActuel.CompareTo(nomprecedent) < 0)
                        {
                            return false;
                        }
 
                    }
 
                }
            }
            return true;
        }
je cherche à factoriser ce code, je pense qu'il y a moyen de faire une requête linq générique, si quelqu'un à une idée la dessus.
Sinon j'étais partie sur une méthode générique similaire à EstTrieeParClassement qui se base sur le nom de la colonne mais ça devient vite trop lourd vu les multiples possibilités (colonne int,string, custom ...)
youtpout978 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 10h19   #2
mirtouf
Candidat au titre de Membre du Club
 
Inscription : janvier 2010
Messages : 33
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 33
Points : 12
Points : 12
Bonjour ,

pour raccourcir un peu le code tu peux peut-être deja faire ca :

Code :
1
2
3
4
5
6
7
8
9
10
 
 switch (sortExpression)
                {
                    case "Nom": GridViewGS.DataSource=(SortDirection == SortDirection.Ascending)?joueurs.OrderBy(j => j.Nom):joueurs.OrderByDescending(j => j.Nom); break; 
                    case "Classement": GridViewGS.DataSource=(!EstTrieeParClassement())?joueurs.OrderBy(j => j.Nom).OrderBy(j => j.Classement):joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.Classement);break;
                    case "NomGuilde": GridViewGS.DataSource=(SortDirection == SortDirection.Ascending)?joueurs.OrderBy(j => j.Nom).OrderBy(j => j.NomGuilde):joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.NomGuilde);break;
                    case "Points": GridViewGS.DataSource=(SortDirection == SortDirection.Ascending)?joueurs.OrderBy(j => j.Nom).OrderBy(j => j.Points):joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.Points);break;
                    case "NbFrags": GridViewGS.DataSource =(SortDirection == SortDirection.Ascending)?joueurs.OrderBy(j => j.Nom).OrderBy(j => j.NbFrags):joueurs.OrderBy(j => j.Nom).OrderByDescending(j => j.NbFrags);break;
                    default: break;
                }
mirtouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 11h08   #3
youtpout978
Membre Expert
 
Homme John Doe
Développeur .NET
Inscription : novembre 2010
Messages : 902
Détails du profil
Informations personnelles :
Nom : Homme John Doe
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : novembre 2010
Messages : 902
Points : 1 439
Points : 1 439
Merci pour ta réponse, l'utilisation d'un opérateur ternaire évite d'utiliser un if else, mais je pensais plus à une méthode que j'appel avec le nom de la propriété et elle effectue le tri sur cette propriété, je ne sais pas si c'est possible à faire sans utiliser la reflexion.
youtpout978 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 14h41   #4
mirtouf
Candidat au titre de Membre du Club
 
Inscription : janvier 2010
Messages : 33
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 33
Points : 12
Points : 12
Et comme ceci ? :


Code :
joueurs = joueurs.OrderBy(x => (x.GetType().GetProperty("Points").GetValue(x, null))).ToList<Joueur>();
mirtouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 14h51   #5
youtpout978
Membre Expert
 
Homme John Doe
Développeur .NET
Inscription : novembre 2010
Messages : 902
Détails du profil
Informations personnelles :
Nom : Homme John Doe
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : novembre 2010
Messages : 902
Points : 1 439
Points : 1 439
Justement c'est de la reflexion et je voulais savoir s'il y avait un moyen de faire autrement.
Mais merci pour ton aide
youtpout978 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 15h12   #6
mirtouf
Candidat au titre de Membre du Club
 
Inscription : janvier 2010
Messages : 33
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 33
Points : 12
Points : 12
Pourquoi ne veux-tu pas utiliser la reflexion ?


Sinon tu peux creer une classe Liste_joueurs comme ceci , et utiliser la methode de tri sans devoir la réecrire dans chaque page:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  public class Liste_joueurs
    {
        List<joueurs> Liste { get; set; }
 
        public void Tri(string SortDirection, string sortExpression)
        {
            switch (sortExpression)
            {
                case "Nom": this.Liste = (SortDirection == "ascending") ? this.Liste.OrderBy(j => j.nom).ToList<joueurs>() : this.Liste.OrderByDescending(j => j.nom).ToList<joueurs>(); break;
                default: break;
            }
        }
 
        public void Tri_par_reflexion(string SortDirection, string sortExpression)
        {
            switch (sortExpression)
            {
                case "Nom": this.Liste = (SortDirection == "ascending") ? Liste.OrderBy(x => (x.GetType().GetProperty("nom").GetValue(x, null))).ToList<joueurs>() : Liste.OrderByDescending(x => (x.GetType().GetProperty("nom").GetValue(x, null))).ToList<joueurs>(); break;
                default: break;
            }
        }
 
    }

Tu peux aussi créer un classe MyPage qui hérite de System.Web.UI.Page
et dedans creer une methode de tri sur une liste de joueurs. Ensuite en faisant hériter tes pages de cette nouvelle classe la methode sera partout accessible.
mirtouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 16h44   #7
youtpout978
Membre Expert
 
Homme John Doe
Développeur .NET
Inscription : novembre 2010
Messages : 902
Détails du profil
Informations personnelles :
Nom : Homme John Doe
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : novembre 2010
Messages : 902
Points : 1 439
Points : 1 439
Cette méthode est utilisé qu'à un seul endroit, le faite de la factoriser c'est juste pour le "sport".
Disons que j'essaye de trouver un moyen pour factoriser ce code sans utiliser la réflexion qui parait-il est couteux.

Après si je suis obligé de passer par la réflexion, je laisserais mon code comme il est actuellement, ce datagrid n'est pas amené à évoluer de toute façon.
youtpout978 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 20h28   #8
mirtouf
Candidat au titre de Membre du Club
 
Inscription : janvier 2010
Messages : 33
Détails du profil
Informations forums :
Inscription : janvier 2010
Messages : 33
Points : 12
Points : 12
Ha ben si c'est pour le sport on peut s'amuser alors

Si tes données proviennent d'une db SQL alors tu peux bidouiller qql chose de comme ca :

Crée une fonction de ce genre dans ta db :

Code :
1
2
3
4
5
6
7
8
9
create FUNCTION dbo.CONSTRUCT_Request
	(
	@value nvarchar(max)
	)
RETURNS nvarchar(max)
AS
	BEGIN
	RETURN 'select  * FROM  Table order by '+@value
	END
Et ensuite crée une procédure stockée :

Code :
1
2
3
4
5
6
7
8
9
CREATE PROCEDURE dbo.GET_Datas
(
@value nvarchar(max)
)
AS
DECLARE @Request nvarchar(max)
SET @Request =dbo.CONSTRUCT_Request(@value)
EXEC sp_executesql @Request
	RETURN
Tu n'auras ensuite plus qu'a faire appel à ta procédure stockée pour chopper tes données :


Code :
1
2
3
4
5
6
7
8
9
10
11
 protected void GridViewGS_Sorting(object sender, GridViewSortEventArgs e)
        {
            try
            {		
		GridViewGS.DataSource=Acces_DB.GET_Datas(e.SortExpression);
	     }
            catch (Exception ex)
            {
                LblErreur.Text = ex.Message;
            }
		}

Bon la il ne reste plus qu'une seule ligne, niveau factorisation je pense que je ne peux pas mieux faire .

Au point de vue temps d'exécution je ne sais pas quelle méthode est la meilleure pour ton site, l'une sollicite plus le serveur web et l'autre le serveur de données.

Par contre en relisant ton code j'ai vu cette ligne quio m'avait échappée la premiere fois :

Code :
List<Joueur> joueurs = ViewState["joueurs"] as List<Joueur>;
Je serai toi je ne stockerais pas ça dans le viewstate , si tu as bcp de données cela va alourdir ta page pour rien.
Tu peux les mettre dans la Session et la virer la de Session une fois que tu quittes cette page.
mirtouf est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/02/2013, 22h55   #9
youtpout978
Membre Expert
 
Homme John Doe
Développeur .NET
Inscription : novembre 2010
Messages : 902
Détails du profil
Informations personnelles :
Nom : Homme John Doe
Localisation : France, Rhône (Rhône Alpes)

Informations professionnelles :
Activité : Développeur .NET

Informations forums :
Inscription : novembre 2010
Messages : 902
Points : 1 439
Points : 1 439
Je suis une grosse feignasse faudrait que je fasse un système de cache pour stocker ces données.
En faite c'est un fichier texte qui est stockée en bdd et depuis ce fichier texte je génère ma liste.
Sinon il faut que je test la libraire linq qui permet d'écrire des requêtes sous format de string.

Là j'essaye de faire un gridview qui est un tableau de score croisé , le contrôle gridview n'as pas l'air de bien s'y prêter faut que je le génère en code on dirait.
youtpout978 est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 09h46.


 
 
 
 
Partenaires

Hébergement Web