how to sort a datagridview by 2 columns

后端 未结 8 1344
北恋
北恋 2020-12-05 08:38

How do I sort a DataGridView by two columns (ascending)? I have two columns: day and status.

If I need to sort by one column, I do:

相关标签:
8条回答
  • 2020-12-05 08:52

    If your DataGridView is databound, you can sort your Datatable view and rebind to datatable as below:

    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
    }
    

    OR, without using bindingsource and binding directly to DataView:

    private void SortDataByMultiColumns()
    {
        DataView view = ds.Tables[0].DefaultView;
        view.Sort = "day ASC, status DESC"; 
        dataGridView1.DataSource = view; //rebind the data source
    }
    
    0 讨论(0)
  • 2020-12-05 08:52

    TLDR; I have a two-line solution.

    I had to do the same thing, but after researching all these complicated ways to do this by either including a separate .dll or writing my own class/methods, I knew there had to be an easier way. It turns out I was right because I figured out how to accomplish this with using only two lines of code. This worked for me.

    Luckily, it turns out for us that the .NET Framework Sort() method does help us with this. The idea is that you want to sort the columns individually, but the order in which you sort them in is what will produce the desired output.

    So, as an example, I have a column for file type and a column for a file name. Whenever I want to sort the data by the types, I want to make sure that the names are also sorted within each type shown.

    GOAL: Sorting by type will also sort the file names alphabetically.

    Data:

    zxcv.css

    testimg3.jpg

    asdf.html

    testimg2.jpg

    testimg1.jpg

    Sorting data by name:

    mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending);
    

    asdf.html

    testimg1.jpg

    testimg2.jpg

    testimg3.jpg

    zxcv.css

    As you can see, this will name sure that the names will be sorted accordingly, such that when I now sort by the file types, both requirements will satisfy.

    Sorting data by file type:

    mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending);
    

    zxcv.css

    asdf.html

    testimg1.jpg

    testimg2.jpg

    testimg3.jpg

    Voila! It's sorted!

    SOLUTION: In your case, you may want to try something like the following, and you may need to tweak it some more to have it cater to your own code.

    DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending);
    DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending);
    

    This should be able to display your results by the day with its status field sorted as well.

    0 讨论(0)
  • 2020-12-05 08:59

    You can use the DataGridView's Sort method, but specify an argument that is an instance of a class that implements IComparer.

    Here is an example of such a class:

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

    Now, we might call this from a column whose SortMode is 'Programmatic' on a mouse click:

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

    The class level variable _SortOrder helps keep track of which order to go in. One can enhance this more to remember the last two columns clicked and sort on them in the desired order.

    0 讨论(0)
  • 2020-12-05 09:00

    You can try this, or use custom sorting:

    private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
            {
                if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day")
                {
                   myBindingSource.Sort = "day, hour";
                }
            }
    
    0 讨论(0)
  • 2020-12-05 09:02

    Add a hidden column that combines the two and sort by that.

    0 讨论(0)
  • 2020-12-05 09:02

    The answer that John Kurtz provided got me close. But what I found was the when I clicked on a column once, it did indeed sort by the two columns ... In his example: dgvcClicked.Name, "LastName". So, good!!

    But, if I clicked on the column again, then it would NOT sort by the opposite direction. So the column became stuck in Ascending.

    To overcome this, I had to track the sort order manually. Started with this class:

    public class ColumnSorting
    {
        public int ColumnIndex { get; set; }
        public ListSortDirection Direction { get; set; }
    }
    

    Then, I added this globally scoped List:

    List<ColumnSorting> _columnSortingList = new List<ColumnSorting>();
    

    Then, in the method that does the Sort, I would

    1. Check to see if the column index being sorted already exists in _columnSortingList. If not, add it.
    2. If it already exists, then swap the sort order

    And Bob's your uncle.

    0 讨论(0)
提交回复
热议问题