Search code examples
c#sortingdatagridviewdatagridviewcolumn

CustomDataGridViewColumn vs DataGridViewTextBoxColumn with custom sort


Hi I currently have a DataGridView where the first column contains the name of a person which until now I've been manually setting the value as a string which represents the Person object. The rest of the columns contain other classes/strings.

I've just been trying to assign the person to the cell value to make it easier to find the person who is attached to that cell. I added the ToString() method to my Person class and all worked well until I tried to sort the column using

_dataGridView.Sort(_dataGridView.Columns[0], ListSortDirection.Ascending);

I get an ArgumentException saying the Object must be of type String (I'm using text box column)

I've tried implementing my own sort method but got an issue with casting the cell value as a Person (says cannot cast string to person) even though I assign a Person as the Value.

public void _rotaView_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
    {
        Person a = (Person)e.CellValue1;
        Person b = (Person)e.CellValue2;

        e.SortResult = a.CompareTo(b);
        e.Handled = true;
    }

Unable to cast object of type 'System.String' to type 'RotaManagerSolution.Person'.

So any ideas on how I can store the custom class in a datagridview cell value and still be able to sort it?


Solution

  • I found the solution to my problem was to databind a custom sortable list to the DataGridView by doing the following

    Create the first column with the data property set to the Name property of the Person class

    // Add column for names (people and shifts)
    DataGridViewColumn names = new DataGridViewTextBoxColumn();
    names.DataPropertyName = "Name";
    names.DefaultCellStyle.BackColor = System.Drawing.Color.Azure;
    names.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    names.SortMode = DataGridViewColumnSortMode.NotSortable;
    _rotaView.Columns.Add(names);
    

    then added this custom sortable binding list found here

    To bind the data

     SortableBindingList<Person> sblist = new SortableBindingList<Person>();
    
     foreach (Person p in _mainManager.ListOfPeople)
     {
         sblist.Add(p);
     }
     _rotaView.DataSource = sblist;
    

    This then allows me to call this line to sort the list

    _rotaView.Sort(_rotaView.Columns[0], System.ComponentModel.ListSortDirection.Ascending);