Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 9 sur 9
  1. #1
    Membre Expert

    Homme Profil pro John Doe
    Développeur .NET
    Inscrit en
    novembre 2010
    Messages
    1 138
    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 : 1 138
    Points : 1 879
    Points
    1 879

    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 ...)

  2. #2
    Candidat au titre de Membre du Club
    Inscrit en
    janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : janvier 2010
    Messages : 33
    Points : 12
    Points
    12

    Par défaut

    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;
                    }

  3. #3
    Membre Expert

    Homme Profil pro John Doe
    Développeur .NET
    Inscrit en
    novembre 2010
    Messages
    1 138
    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 : 1 138
    Points : 1 879
    Points
    1 879

    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
    Candidat au titre de Membre du Club
    Inscrit en
    janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : janvier 2010
    Messages : 33
    Points : 12
    Points
    12

    Par défaut

    Et comme ceci ? :


    Code :
    joueurs = joueurs.OrderBy(x => (x.GetType().GetProperty("Points").GetValue(x, null))).ToList<Joueur>();

  5. #5
    Membre Expert

    Homme Profil pro John Doe
    Développeur .NET
    Inscrit en
    novembre 2010
    Messages
    1 138
    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 : 1 138
    Points : 1 879
    Points
    1 879

    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
    Candidat au titre de Membre du Club
    Inscrit en
    janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : janvier 2010
    Messages : 33
    Points : 12
    Points
    12

    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 :
    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
    Membre Expert

    Homme Profil pro John Doe
    Développeur .NET
    Inscrit en
    novembre 2010
    Messages
    1 138
    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 : 1 138
    Points : 1 879
    Points
    1 879

    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
    Candidat au titre de Membre du Club
    Inscrit en
    janvier 2010
    Messages
    33
    Détails du profil
    Informations forums :
    Inscription : janvier 2010
    Messages : 33
    Points : 12
    Points
    12

    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 :
    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.

  9. #9
    Membre Expert

    Homme Profil pro John Doe
    Développeur .NET
    Inscrit en
    novembre 2010
    Messages
    1 138
    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 : 1 138
    Points : 1 879
    Points
    1 879

    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.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •