如何按2列对datagridview进行排序
如何按两列(升序)对DataGridView进行排序? 我有两列: day
和status
。
如果我需要按一列排序,我会:
this.dataGridView1.Sort (this.dataGridView1.Columns["day"], ListSortDirection.Ascending);
但对于两个?
如果您的DataGridView
是数据绑定,您可以对Datatable
视图进行排序并重新绑定到datatable,如下所示:
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 }
或者,不使用bindingsource并直接绑定到DataView
:
private void SortDataByMultiColumns() { DataView view = ds.Tables[0].DefaultView; view.Sort = "day ASC, status DESC"; dataGridView1.DataSource = view; //rebind the data source }
添加一个隐藏列,将两者结合起来并按其排序。
TLDR; 我有一个双线解决方案。
我必须做同样的事情,但在研究了所有这些复杂的方法,通过包括一个单独的.dll或编写我自己的类/方法来做到这一点,我知道必须有一个更简单的方法。 事实certificate我是对的,因为我想通过仅使用两行代码来实现这一目标。 这对我有用。
幸运的是,我们发现.NET Framework Sort()方法确实帮助了我们。 这个想法是你想要单独对列进行排序,但是你对它们进行排序的顺序是产生所需输出的顺序。
因此,作为示例,我有一个文件类型列和一个文件名列。 每当我想按类型对数据进行排序时,我想确保名称也在显示的每种类型中排序。
目标:按类型排序还将按字母顺序对文件名进行排序。
数据:
zxcv.css
testimg3.jpg
asdf.html
testimg2.jpg
testimg1.jpg
按名称排序数据:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending);
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
zxcv.css
正如您所看到的,这将确定名称将相应地进行排序,这样当我现在按文件类型排序时,两个要求都将满足。
按文件类型排序数据:
mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending);
zxcv.css
asdf.html
testimg1.jpg
testimg2.jpg
testimg3.jpg
瞧! 它排序了!
解决方案:在您的情况下,您可能希望尝试以下内容,您可能需要进一步调整它以满足您自己的代码。
DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending); DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending);
这应该能够在当天显示您的结果,其状态字段也已排序。
您可以使用DataGridView的Sort方法,但指定一个参数,该参数是实现IComparer的类的实例。
以下是此类的示例:
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; } }
现在,我们可以通过鼠标单击的SortMode为“Programmatic”的列来调用它:
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); } }
类级变量_SortOrder有助于跟踪要进入的顺序。可以进一步增强这一点以记住单击的最后两列并按所需顺序对它们进行排序。
您可以尝试这个 ,或使用自定义排序:
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day") { myBindingSource.Sort = "day, hour"; } }
John Kurtz提供的答案让我很接近。 但我发现的是当我点击一次列时,确实按两列排序……在他的例子中:dgvcClicked.Name,“LastName”。 超好的!!
但是,如果我再次点击该列,那么它将不会按相反的方向排序。 因此该专栏陷入了Ascending。
为了解决这个问题,我必须手动跟踪排序顺序。 从这门课开始:
public class ColumnSorting { public int ColumnIndex { get; set; } public ListSortDirection Direction { get; set; } }
然后,我添加了这个全局范围的List:
List _columnSortingList = new List ();
然后,在执行排序的方法中,我会
- 检查_columnSortingList中是否已存在已排序的列索引。 如果没有,请添加它。
- 如果它已存在,则交换排序顺序
而鲍勃是你的叔叔。