Comment trier un DataGridView en deux colonnes (croissant)? J'ai deux colonnes: day
et status
.
Si j'ai besoin de trier par une colonne, je fais:
this.dataGridView1.Sort (this.dataGridView1.Columns["day"], ListSortDirection.Ascending);
Mais pour deux?
Si votre DataGridView
est databound, vous pouvez trier votre vue Datatable
et la lier de nouveau à datatable comme suit:
private DataGridView dataGridView1 = new DataGridView();
private BindingSource bindingSource1 = new BindingSource();
private void Form1_Load(object sender, System.EventArgs e)
{
// Bind the DataGridView to the BindingSource
dataGridView1.DataSource = bindingSource1;
SortDataByMultiColumns(); //Sort the Data
}
private void SortDataByMultiColumns()
{
DataView view = dataTable1.DefaultView;
view.Sort = "day ASC, status DESC";
bindingSource1.DataSource = view; //rebind the data source
}
OU, sans utiliser bindingsource ni se lier directement à DataView
:
private void SortDataByMultiColumns()
{
DataView view = ds.Tables[0].DefaultView;
view.Sort = "day ASC, status DESC";
dataGridView1.DataSource = view; //rebind the data source
}
Ajouter une colonne cachée qui combine les deux et trier par cela.
TLDR; J'ai une solution à deux lignes.
Je devais faire la même chose, mais après avoir recherché toutes ces méthodes compliquées en incluant un fichier .dll séparé ou en écrivant mon propre cours/méthodes, je savais qu'il devait exister un moyen plus simple. Il s’avère que j’avais raison, car j’ai trouvé comment y parvenir en utilisant seulement deux lignes de code. Cela a fonctionné pour moi.
Heureusement, il s’avère que la méthode .NET Framework Sort () nous aide à cet égard. L'idée est que vous souhaitiez trier les colonnes individuellement, mais l'ordre dans lequel vous les triez est ce qui produira la sortie souhaitée.
Ainsi, à titre d'exemple, j'ai une colonne pour le type de fichier et une colonne pour un nom de fichier. Chaque fois que je veux trier les données selon les types, je veux m'assurer que les noms sont également triés dans chaque type affiché.
OBJECTIF: Le tri par type triera également les noms de fichiers par ordre alphabétique.
Les données:
zxcv.css
testimg3.jpg
asdf.html
testimg2.jpg
testimg1.jpg
Tri des données par nom:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending);
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
zxcv.css
Comme vous pouvez le constater, cela garantira que les noms seront triés en conséquence, de sorte que lorsque je trie maintenant en fonction des types de fichiers, les deux exigences seront satisfaites.
Tri des données par type de fichier:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending);
zxcv.css
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
Voila! C'est trié!
SOLUTION: Dans votre cas, vous voudrez peut-être essayer quelque chose comme ce qui suit, et vous devrez peut-être un peu plus le modifier pour qu'il s'adapte à votre code.
DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending);
DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending);
Cela devrait pouvoir afficher vos résultats par jour avec son champ d’état également trié.
Vous pouvez utiliser la méthode Sort du DataGridView, mais spécifier un argument qui est une instance d'une classe qui implémente IComparer.
Voici un exemple d'une telle classe:
public class MyTwoColumnComparer : System.Collections.IComparer
{
private string _SortColumnName1;
private int _SortOrderMultiplier1;
private string _SortColumnName2;
private int _SortOrderMultiplier2;
public MyTwoColumnComparer(string pSortColumnName1, SortOrder pSortOrder1, string pSortColumnName2, SortOrder pSortOrder2)
{
_SortColumnName1 = pSortColumnName1;
_SortOrderMultiplier1 = (pSortOrder1 == SortOrder.Ascending) ? 1 : -1;
_SortColumnName2 = pSortColumnName2;
_SortOrderMultiplier2 = (pSortOrder2 == SortOrder.Ascending) ? 1 : -1;
}
public int Compare(object x, object y)
{
DataGridViewRow r1 = (DataGridViewRow)x;
DataGridViewRow r2 = (DataGridViewRow)y;
int iCompareResult = _SortOrderMultiplier1 * String.Compare(r1.Cells[_SortColumnName1].Value.ToString(), r2.Cells[_SortColumnName1].Value.ToString());
if (iCompareResult == 0) iCompareResult = _SortOrderMultiplier2 * String.Compare(r1.Cells[_SortColumnName2].Value.ToString(), r2.Cells[_SortColumnName2].Value.ToString());
return iCompareResult;
}
}
Maintenant, nous pourrions appeler cela depuis une colonne dont SortMode est 'Programmatic' en un clic de souris:
private void dgvAllMyEmployees_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
DataGridViewColumn dgvcClicked = dgvAllEmployees.Columns[e.ColumnIndex];
if (dgvcClicked.SortMode == DataGridViewColumnSortMode.Programmatic)
{
_SortOrder = (_SortOrder == SortOrder.Ascending) ? SortOrder.Descending : SortOrder.Ascending;
MyTwoColumnComparer Sort2C = new MyTwoColumnComparer(dgvcClicked.Name, _SortOrder, "LastName", SortOrder.Ascending);
dgvAllEmployees.Sort(Sort2C);
}
}
La variable de niveau de classe _SortOrder aide à garder une trace de l'ordre dans lequel entrer. On peut améliorer ceci davantage pour se souvenir des deux dernières colonnes cliquées et les trier dans l'ordre souhaité.
Vous pouvez essayer this , ou utiliser un tri personnalisé:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day")
{
myBindingSource.Sort = "day, hour";
}
}
La réponse fournie par John Kurtz m'a rapproché. Mais ce que j’ai trouvé, c’est quand j’ai cliqué sur une colonne une fois, elle s’est bien triée par les deux colonnes ... Dans son exemple: dgvcClicked.Name, "LastName". Tellement bon!!
Mais si je cliquais à nouveau sur la colonne, elle ne trierait PAS par la direction opposée. Donc, la colonne est restée bloquée dans Ascending.
Pour surmonter cela, je devais suivre l'ordre de tri manuellement. Commencé avec ce cours:
public class ColumnSorting
{
public int ColumnIndex { get; set; }
public ListSortDirection Direction { get; set; }
}
Ensuite, j'ai ajouté cette liste globale:
List<ColumnSorting> _columnSortingList = new List<ColumnSorting>();
Ensuite, dans la méthode qui fait le tri, je voudrais
Et Bob est ton oncle.