Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a DataGridView assigned to this query.

dgvArtists.DataSource = (from a in context.Artists
                              orderby a.BirthName
                              select new
                              {
                                  a.ArtistId,
                                  a.BirthName,
                                  a.DateOfBirth,
                                  a.Songs.Count
                              }).ToList();

When I click on the header, I want it to sort, but I keep getting this error.
'DataGridView control must be bound to an IBindingList object to be sorted.'


This is the header method that is being activated where I am getting the error:
private void dgvArtists_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (dgvArtists.Columns[e.ColumnIndex].SortMode != DataGridViewColumnSortMode.NotSortable)
            {
                if (e.ColumnIndex == newSortColumn)
                {
                    if (newColumnDirection == ListSortDirection.Ascending)
                        newColumnDirection = ListSortDirection.Descending;
                    else
                        newColumnDirection = ListSortDirection.Ascending;
                }

                newSortColumn = e.ColumnIndex;

                switch (newColumnDirection)
                {
                    case ListSortDirection.Ascending:
                        dgvArtists.Sort(dgvArtists.Columns[newSortColumn], ListSortDirection.Ascending);
                        break;
                    case ListSortDirection.Descending:
                        dgvArtists.Sort(dgvArtists.Columns[newSortColumn], ListSortDirection.Descending);
                        break;
                }
            }
        }


What I have tried:

I have read:
Implementing a Sortable BindingList Very, Very Quickly[^] but I do not know what do put in for:
MySortableBindingList<SaleDetails>sortableSaleDetails = 
                      new MySortableBindingList<SaleDetail>();

I've created a class that only contains the properties I want it to return like it says in: Cannot convert from System.Linq.IQueryable<AnonymousType> to System.Collections.Generic.IEnumerable<myobject>[^]
class ArtistList
    {
        public int ArtistId { get; set; }
        public string Last_Name { get; set; }
        public int Age { get; set; }
        public int Song_Count  { get; set; }
    }

List<ArtistList> xList = new List<ArtistList>();

            xList = (from a in context.Artists
                orderby a.BirthName
                select new ArtistList
                {
                    ArtistId = a.ArtistId,
                    Last_Name = a.BirthName.Split(space).Last(),
                    Age = a.DateOfDeath.HasValue ?
                        (Convert.ToDateTime(a.DateOfDeath).Year - a.DateOfBirth.Year) :
                        (DateTime.Today.Year - a.DateOfBirth.Year),
                    Song_Count = a.Songs.Count

                }).ToList();

            dgvArtists.DataSource = xList;
Posted
Updated 3-Aug-22 9:35am
v2
Comments
Richard MacCutchan 1-Aug-22 3:55am    
Your datasource is created dynamically so it no longer exists after it has been fed into the DataGridView. You need to create an actual List<T> from the LINQ code, and bind that to the DataGridView.
User-15670402 1-Aug-22 12:12pm    
Would you be able to provide an example of how I would do that?
Richard MacCutchan 1-Aug-22 12:14pm    
You already have the code, just pass the LINQ commands to your List.
User-15670402 1-Aug-22 13:07pm    
I am so sorry, but this is my first time working with DataGridViews and LINQ. When I say I have the code and just need to pass the LINQ command, isn't that what I did with the ToList()?
Richard MacCutchan 2-Aug-22 3:18am    
Yes, but that creates a dynamic list whose members (individual list items) are passed to the DataGridView, which adds them row by row. The dynamic list itself no longer exists so any attempt to modify it will fail. What you need is a physical datasource that can be changed as required. So you need something like:
List<T> datalist = new List<T>;
datalist = from a in context.Artists ... etc.
dgvArtists.DataSource = datalist;

You can now modify the datalist any time and refresh the DataGridView to reflect the changes.

1 solution

Your question has been answered here: How do I get list<T> to ibindinglist object?[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900