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";
}
}
}
5 Réponses :
La première fois que j'ai lu ceci, j'ai totalement manqué la partie sur le tri par plusieurs colonnes em> simultanément (ma faute, pas la vôtre; la question était parfaitement claire). P>
Si c'est le cas, vous allez devoir écrire le code qui vous gère vous-même. Le contrôle code> DataGridView DataGridView fournie ne prend pas en charge le tri multi-colonnes par défaut. Heureusement, d'autres ont déjà fait beaucoup de travail pour la mettre en œuvre pour vous. Voici quelques échantillons: P>
Alternativement, si vous liez votre Pour ce faire, attachez un gestionnaire au Vous pouvez également choisir de dériver une nouvelle classe de
datagridview code> à une source de données, la source de données peut être triée sur plusieurs colonnes et le contrôle
dataGridView CODE> Respectera ce tri. Toute source de données qui implémente
ibindingListview code> et expose un
Trier la propriété code> fonctionnera pour le tri multi-colonnes. P>
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 code> 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. P>
datagridview.Cellpainting code> événement
et recherchez un Rowindex code> 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. P>
datagridviewcolumnheeCell code>
et remplacer son peinture code> méthode
. Ceci est probablement une manière plus propre et plus orientée objet d'accomplir la même chose. P>
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.
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) em> et le DGV peint maintenant plusieurs glyphes de tri multiples. P> < Pré> xxx pré> p>
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 ?
Quand 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
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 / )
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).
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: p>
Nous commençons par un objet de trieur: p> puis collectez nos objets de trieur dans une classe de trieurs: p> 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: p> 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: p>
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 code> iirc.