C# DataGridView sorting with Generic List as underlying source

前端 未结 9 1812
情书的邮戳
情书的邮戳 2020-12-05 03:22

I\'m using a Windows Forms DataGridView to display a generic list of MyObject objects.

First of all I wrap this collection into a

相关标签:
9条回答
  • 2020-12-05 03:31

    Another option to solve the sorting issue with DataGridView when binding to List is, if you are not dealing with huge data set then probably you can attempt to convert the List to DataTable, and then bind the resulting DataTable to the BindingSource/DataGridView.

    This would the need for a custom implementation of IComparer. In my case, I was dealing with a smaller list but there were more fields to display. So implementing IComparer meant writing too much boiler plate code.

    Check this for terse way of converting the List to DataTable: https://stackoverflow.com/a/34062898/4534493

    0 讨论(0)
  • 2020-12-05 03:40

    You may also want to take a look to this post where you can get two interesting links to implement a customized SortableBindingList:

    Sort Datagridview columns when datasource binded to List(Of T)

    0 讨论(0)
  • 2020-12-05 03:43

    My Solution is this:

    I work with myBindingSource at my own, I do sorting, grouping ..whatever in a separate thread. Then I simply bind the result to the DataGridView.

    myDataGridView.DataSource = bindingSource;
    

    For this purpose I've setted all the columns to be sorted 'Programatically' (in designer) Then I manually add the arrow (ASCENDING / DESCENDING) by setting

    cell.SortGlyphDirection = ... ; 
    

    in code behind.

    0 讨论(0)
  • 2020-12-05 03:45

    Complete code to sort the column of datagridview whose datasource is a generic List

    //-----------------------------------------------------------------------------------------
    //In the form - In constructor or form load, populate the grid.
    //--------------------------------------------------------------------------------------------
    
        List<student> students;
    
        private void PopulateList()
        {
            student std1 = new student("sss", 15, "Female");
            student std2 = new student("ffffd", 12, "Male");
            student std3 = new student("zzz", 16, "Male");
            student std4 = new student("qqq", 14, "Female");
            student std5 = new student("aaa", 11, "Male");
            student std6 = new student("lll", 13, "Female");
    
            students = new List<student>();
            students.Add(std1);
            students.Add(std2);
            students.Add(std3);
            students.Add(std4);
            students.Add(std5);
            students.Add(std6);
    
            dataGridView1.DataSource = students;
        }
    
    
    //---------------------------------------------------------------------------------------------
    //Comparer class to perform sorting based on column name and sort order
    //---------------------------------------------------------------------------------------------
    
    
    class StudentComparer : IComparer<Student>
    {
        string memberName = string.Empty; // specifies the member name to be sorted
        SortOrder sortOrder = SortOrder.None; // Specifies the SortOrder.
    
        /// <summary>
        /// constructor to set the sort column and sort order.
        /// </summary>
        /// <param name="strMemberName"></param>
        /// <param name="sortingOrder"></param>
        public StudentComparer(string strMemberName, SortOrder sortingOrder)
        {
            memberName = strMemberName;
            sortOrder = sortingOrder;
        }
    
        /// <summary>
        /// Compares two Students based on member name and sort order
        /// and return the result.
        /// </summary>
        /// <param name="Student1"></param>
        /// <param name="Student2"></param>
        /// <returns></returns>
        public int Compare(Student Student1, Student Student2)
        {
            int returnValue = 1;
            switch (memberName)
            {
                case "Name" :
                    if (sortOrder == SortOrder.Ascending)
                    {
                        returnValue = Student1.Name.CompareTo(Student2.Name);
                    }
                    else
                    {
                        returnValue = Student2.Name.CompareTo(Student1.Name);
                    }
    
                    break;
                case "Sex":
                    if (sortOrder == SortOrder.Ascending)
                    {
                        returnValue = Student1.Sex.CompareTo(Student2.Sex);
                    }
                    else
                    {
                        returnValue = Student2.Sex.CompareTo(Student1.Sex);
                    }
                    break;
                default:
                    if (sortOrder == SortOrder.Ascending)
                    {
                        returnValue = Student1.Name.CompareTo(Student2.Name);
                    }
                    else
                    {
                        returnValue = Student2.Name.CompareTo(Student1.StudentId);
                    }
                    break;
            }
            return returnValue;
        }
    }
    
    
    
    //---------------------------------------------------------------------------------------------
    // Performing sort on click on Column Header
    //---------------------------------------------------------------------------------------------
    
        private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //get the current column details
            string strColumnName = dataGridView1.Columns[e.ColumnIndex].Name;
            SortOrder strSortOrder = getSortOrder(e.ColumnIndex);
    
            students.Sort(new StudentComparer(strColumnName, strSortOrder));
            dataGridView1.DataSource = null;
            dataGridView1.DataSource = students;
            customizeDataGridView();
            dataGridView1.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = strSortOrder;
        }
    
       /// <summary>
        /// Get the current sort order of the column and return it
        /// set the new SortOrder to the columns.
        /// </summary>
        /// <param name="columnIndex"></param>
        /// <returns>SortOrder of the current column</returns>
        private SortOrder getSortOrder(int columnIndex)
        {
            if (dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.None ||
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection == SortOrder.Descending)
            {
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
                return SortOrder.Ascending;
            }
            else
            {
                dataGridView1.Columns[columnIndex].HeaderCell.SortGlyphDirection = SortOrder.Descending;
                return SortOrder.Descending;
            }
        }
    
    0 讨论(0)
  • 2020-12-05 03:52

    see this artice

    http://msdn.microsoft.com/en-us/library/0868ft3z.aspx

    by reading it i saw this "This method sorts the contents of the DataGridView by comparing values in the specified column. By default, the sort operation will use the Compare method to compare pairs of cells in the column using the DataGridViewCell..::.Value property."

    Best Regards, iordan

    0 讨论(0)
  • 2020-12-05 03:52

    If creating your own user control is preferable, you can make a custom sort method using the code below:

        private string _lastSortColumn;
        private ListSortDirection _lastSortDirection;
    
        public void Sort(DataGridViewColumn column)
        {
            // Flip sort direction, if the column chosen was the same as last time
            if (column.Name == _lastSortColumn)
                _lastSortDirection = 1 - _lastSortDirection;
            // Otherwise, reset the sort direction to its default, ascending
            else
            {
                _lastSortColumn = column.Name;
                _lastSortDirection = ListSortDirection.Ascending;
            }
    
            // Prep data for sorting
            var data = (IEnumerable<dynamic>)DataSource;
            var orderProperty = column.DataPropertyName;
    
            // Sort data
            if (_lastSortDirection == ListSortDirection.Ascending)
                DataSource = data.OrderBy(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();
            else
                DataSource = data.OrderByDescending(x => x.GetType().GetProperty(orderProperty).GetValue(x, null)).ToList();
    
            // Set direction of the glyph
            Columns[column.Index].HeaderCell.SortGlyphDirection
                = _lastSortDirection == ListSortDirection.Ascending
                ? SortOrder.Ascending : SortOrder.Descending;
        }
    

    You can then override the header click method to call your sort function:

        protected override void OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
        {
            base.OnColumnHeaderMouseClick(e);
    
            var column = Columns[e.ColumnIndex];
    
            if (column.SortMode == DataGridViewColumnSortMode.Automatic
                || column.SortMode == DataGridViewColumnSortMode.NotSortable)
                Sort(column);
        }
    
    0 讨论(0)
提交回复
热议问题