8
votes

Trier un DataGridView sur plusieurs colonnes?

J'ai recherché un exemple de tri de DataGridView sur plusieurs colonnes, mais ne semble pas pouvoir trouver un exemple qui fait ce que je voudrais.

Fondamentalement, j'ai un contrôle de DataGridView borns (lié à un fichier de données / dataview), et le jeu de données lié dispose de deux colonnes: - priorité et date. Je voudrais trier par date dans la priorité. C'est-à-dire que la colonne prioritaire prend prépendence, alors sa date, mais les deux peuvent être ascendantes ou descendantes. P>

Donc, par exemple, je peux avoir une priorité basse, début de début (commander par priorité ASC , date ASC) em> et, en cliquant sur l'en-tête de la colonne de date, passez à la priorité à faible priorité, de la date tardive d'abord (commande par priorité ASC, date descendez-la>. Si je clique ensuite sur la priorité, j'aimerais avoir une priorité élevée d'abord, puis la date tardive (ordre de tri actuel de la colonne de date - ordre par priorité Desc, date de descente>, puis être capable de Pour cliquer sur l'en-tête de la colonne Date pour passer à une priorité élevée, Date précoce (commande par la priorité desc, date ASC) em>. p>

Idéalement, je voudrais trier les glyphes sur les deux colonnes à montrer ascendant ou descendant. p>

Des idées ou des pointeurs seraient reçus avec gratitude. P>

Ceci (voir ci-dessous) semble être assez proche, mais les glyphes ne fonctionnent pas correctement. P >

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication4
{
  public partial class Form1 : Form
  {
     DataSet1 dataset;

     public Form1()
     {
        InitializeComponent();

        dataset = new DataSet1(); // two columns: Priority(Int32) and date (DateTime)
        dataset.DataTable1.AddDataTable1Row(1, DateTime.Parse("01-jan-10"));
        dataset.DataTable1.AddDataTable1Row(1, DateTime.Parse("02-jan-10"));
        dataset.DataTable1.AddDataTable1Row(1, DateTime.Parse("03-jan-10"));
        dataset.DataTable1.AddDataTable1Row(2, DateTime.Parse("04-jan-10"));
        dataset.DataTable1.AddDataTable1Row(2, DateTime.Parse("05-jan-10"));
        dataset.DataTable1.AddDataTable1Row(2, DateTime.Parse("06-jan-10"));
        dataset.DataTable1.AddDataTable1Row(3, DateTime.Parse("07-jan-10"));
        dataset.DataTable1.AddDataTable1Row(3, DateTime.Parse("08-jan-10"));
        dataset.DataTable1.AddDataTable1Row(3, DateTime.Parse("09-jan-10"));

        dataGridView1.DataSource = dataset.DataTable1.DefaultView;

        dataGridView1.AllowUserToAddRows = false;

        dataGridView1.Columns[0].SortMode = DataGridViewColumnSortMode.Programmatic;
        dataGridView1.Columns[1].SortMode = DataGridViewColumnSortMode.Programmatic;

        dataGridView1.Columns[0].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
        dataGridView1.Columns[1].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
     }

     private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
     {
        DataGridViewColumn[] column = new[] { dataGridView1.Columns[0], dataGridView1.Columns[1] };

        DataGridViewColumnHeaderCell headerCell = dataGridView1.Columns[e.ColumnIndex].HeaderCell;

        if (headerCell.SortGlyphDirection != SortOrder.Ascending)
           headerCell.SortGlyphDirection = SortOrder.Ascending;
        else
           headerCell.SortGlyphDirection = SortOrder.Descending;

        String sort = column[0].DataPropertyName + " " + fnSortDirection(column[0])
                    + ", "
                    + column[1].DataPropertyName + " " + fnSortDirection(column[1]);
        dataset.DataTable1.DefaultView.Sort = sort;
        this.textBox1.Text = sort;
     }

     private String fnSortDirection(DataGridViewColumn column)
     {
        return column.HeaderCell.SortGlyphDirection != SortOrder.Descending ? "asc" : "desc";
     }
  }
}


3 commentaires

Qu'entendez-vous par «ne pas fonctionner de droite» en ce qui concerne les glyphes arrow? Je ne voulais vraiment pas prendre le temps d'écrire le code de tri, mais j'ai eu ceci à l'air juste auparavant, et cela ressemble à ce que vous êtes la plupart du temps là maintenant.


Eh bien ... le glyphe pour la première colonne (priorité) bascule entre de haut en bas, mais le glyphe de la deuxième colonne semble être une sorte de trois états et s'affiche plus, rien, rien. Je suppose que le DGV n'aime pas vraiment avoir deux glyphes de tri en même temps? J'ai ajouté une troisième colonne avec le tri "normal" et qui semble bien mais (avec les glyphes sur les deux premières colonnes disparaissant), mais en cliquant sur l'en-tête de la 2e colonne, me donne un glyphe ascendant sur la 1ère colonne.


Google pour multisortDataGridView iirc.


5 Réponses :


7
votes

La première fois que j'ai lu ceci, j'ai totalement manqué la partie sur le tri par plusieurs colonnes simultanément (ma faute, pas la vôtre; la question était parfaitement claire).

Si c'est le cas, vous allez devoir écrire le code qui vous gère vous-même. Le contrôle DataGridView

  • DataGridView Tri multi-colonne (codeProject)
  • Comment permet de trier par plusieurs colonnes dans la liaison de données personnalisée (codeProject )

    Alternativement, si vous liez votre datagridview à une source de données, la source de données peut être triée sur plusieurs colonnes et le contrôle dataGridView Respectera ce tri. Toute source de données qui implémente ibindingListview et expose un Trier la propriété fonctionnera pour le tri multi-colonnes.


    Cependant, quel que soit l'itinéraire que vous choisissez d'activer le tri multi-colonnes, vous n'allez pas avoir beaucoup de succès pour contraindre le datagridview pour afficher la flèche de tri glyphe sur plusieurs colonnes. La solution la plus simple ici est de ne pas tirer sur mesure uniquement les en-têtes de colonne pour fournir votre propre glyphe de tri.

    Pour ce faire, attachez un gestionnaire au datagridview.Cellpainting événement et recherchez un Rowindex de -1 (indiquant une en-tête de colonne). Il y a un échantillon complet d'en-têtes de colonne dessinés au propriétaire ici . Je recommande vivement de coller avec l'icône de flèche conventionnelle, mais une fois que vous êtes allé cette route, les options sont vraiment illimitées. Vous pouvez faire ressembler vos en-têtes de colonne, et même indiquer le poids relatif de chaque colonne dans l'ordre de tri en utilisant différentes icônes.

    Vous pouvez également choisir de dériver une nouvelle classe de datagridviewcolumnheeCell et remplacer son peinture méthode . Ceci est probablement une manière plus propre et plus orientée objet d'accomplir la même chose.


1 commentaires

Cody, merci beaucoup d'avoir pris le temps de suggérer une solution - il est grandement apprécié. Je suis allé avec la méthode de la tête de tête / Onpaint, mais je pourrais également enquêter sur vos autres suggestions.



4
votes

OK.

Suivre les suggestions de Cody ci-dessus, j'ai maintenant quelque chose qui semble fonctionner comme prévu. J'ai sous-classé la tête de tête et surchargé la méthode de la peinture (mais triché en définissant le sortglyphdrection immédiatement avant la base.paint) et le DGV peint maintenant plusieurs glyphes de tri multiples. < Pré> xxx


1 commentaires

J'ai jeté dans les trucs de Linq juste pour le plaisir, mais je ne suis pas convaincu que c'est une bonne approche (surtout l'extension "foreach"). Les pensées ?



4
votes

Quand DATAGRIDView strong> se lie à la forte> DataSource forte> ( DataView, liaison, table, DataSet + "Nom" em>) Dans tous les cas, il s'agit du DataView strong>. Faites référence à ce DataView et définissez TRIER STRY> (et FILTER FORT>) Comme vous le souhaitez: XXX PRE>

Remarque: Noms de colonne utilisés dans Trier et filtrer correspondent aux noms de colonne de DataTable forts>, Les noms de colonnes dans DataGridView sont les noms de propriété de données sous-jacents utilisés pour la liaison (noms de propriété pour les classes, les noms de colonne pour tatables, etc.). Vous pouvez obtenir un nom de colonne utilisé dans DataView comme ceci: P>

string colName = dgv.Columns[colIdx].DataPropertyName


0 commentaires

2
votes

Je n'ai jamais répondu à une question ici, alors je m'excuse si le format est incorrect, mais j'ai trouvé une réponse à cette question qui peut être plus simple pour les futurs visiteurs. (Voir http://www.pcreview.co.uk/threads/DataGridView- glyphs.3145090 / ) xxx


3 commentaires

Pouvez-vous s'il vous plaît expliquer pourquoi cela aiderait la lumière noire avec leur problème?


Eh bien, j'ai compris que la question de la lumière noire est qu'ils veulent avoir un tri primaire et secondaire sur des colonnes liées à un DataView, puis d'avoir des glyphes sur chaque en-tête indiquant dans quelle direction il trie. Ce code donne la priorité dans l'ordre que les colonnes sont triées, la colonne la plus récente à trier la plus haute priorité. Il montre également des glyphes de direction sur chaque colonne.


J'ai créé un gestionnaire d'événements de cellules de cellule et définissez le SortGlyphDirection comme indiqué dans le code exemple. Lorsque je trie par une colonne, l'en-tête de colonne flèche et désactive. Lorsque je trie par deux colonnes ou plus, le glyphe de tri de la colonne n'est affiché que sur la dernière colonne triée (la plus droite).



0
votes

Voici un exemple qui fonctionne comme Google Spreadsheets - en cliquant sur chaque en-tête de colonne par cette colonne, puis en cliquant à nouveau sur la colonne, sonne la direction de la recherche. En outre, il recherche dans l'ordre inverse de l'historique de la manière dont vous avez cliqué sur les colonnes, c'est-à-dire que si vous cliquez sur la colonne d, alors bin ce que a, à ce dernier clic, il triera par colonnes A, C, B, D et Dans la direction de chacun que celle-ci recherchait lorsque vous avez récemment cliqué sur cette colonne.

Il repose sur ces fonctions intégrées à la DataGridView:

  • Si DataGridView a un DataView comme DataSource, puis définissez la chaîne de tri pour ce type de DataView entraîne un tri immédiat du DataView et que le tri indique immédiatement dans le contrôle de DataGriDView Nature
  • La chaîne de tri peut inclure plusieurs colonnes, chacune pouvant être indiquée pour trier l'ASC ou DESC
  • Lorsque vous définissez la chaîne de tri du DataView (le faisant trier), le DataGridView auquel il est consolidé ajoutera le glyphe haut de gymnastique approprié automatiquement en fonction du premier élément (nom et direction) dans votre tri chaîne

    Nous commençons par un objet de trieur: xxx

    puis collectez nos objets de trieur dans une classe de trieurs: xxx

    Et je fais ma propre classe MultisortingingDataGridViewViewView, dérivant de DataGridView, avec une méthode de tri remplacée qui garde une trace de laquelle des colonnes que vous avez cliquées et provoque une sorte de DataView qui est la source de données liée à ma grille, en fonction de L'historique de vos clics de tri de colonne: xxx

    puis dans mon formulaire, je m'assure que j'utilise un contrôle multisortingtingDataGridView (comme ci-dessus) au lieu de la DataGridView régulière, et j'ai défini sa source de données comme ceci: xxx


0 commentaires