IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Factoriser code de tri gridview


Sujet :

ASP.NET

  1. #1
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut Factoriser code de tri gridview
    Bonjour,
    j'ai un gridview bindé à une liste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ▼" SortExpression="Classement">
                        <HeaderStyle Wrap="False" />
                        <ItemStyle HorizontalAlign="Center" />
                    </asp:BoundField>
                    <asp:TemplateField HeaderText="Nom ▼" 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 ▼" 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 ▼" SortExpression="Points">
                        <ItemStyle HorizontalAlign="Center" />
                        <HeaderStyle Wrap="False" />
                    </asp:BoundField>
                    <asp:BoundField DataField="NbFrags" HeaderText="Frags ▼" 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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ...)

  2. #2
    Membre à l'essai
    Inscrit en
    Janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    Bonjour ,

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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;
                    }

  3. #3
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    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.

  4. #4
    Membre à l'essai
    Inscrit en
    Janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    Et comme ceci ? :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    joueurs = joueurs.OrderBy(x => (x.GetType().GetProperty("Points").GetValue(x, null))).ToList<Joueur>();

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    Justement c'est de la reflexion et je voulais savoir s'il y avait un moyen de faire autrement.
    Mais merci pour ton aide

  6. #6
    Membre à l'essai
    Inscrit en
    Janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  7. #7
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    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.

  8. #8
    Membre à l'essai
    Inscrit en
    Janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : Janvier 2010
    Messages : 33
    Points : 22
    Points
    22
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  9. #9
    Expert confirmé

    Homme Profil pro
    Développeur .NET
    Inscrit en
    Novembre 2010
    Messages
    2 065
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Novembre 2010
    Messages : 2 065
    Points : 4 229
    Points
    4 229
    Par défaut
    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.

Discussions similaires

  1. Tri gridView avec callBack
    Par sunvialley dans le forum ASP.NET
    Réponses: 5
    Dernier message: 03/09/2008, 10h52
  2. Question d'écriture de code (bloc Try)
    Par Paul Van Walleghem dans le forum VB.NET
    Réponses: 3
    Dernier message: 25/06/2008, 16h36
  3. Réponses: 4
    Dernier message: 14/12/2007, 09h57
  4. Tri gridview avec Template
    Par Prodige2020 dans le forum ASP.NET
    Réponses: 4
    Dernier message: 17/08/2007, 11h15
  5. Réponses: 2
    Dernier message: 27/10/2005, 15h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo