This is my first c# application so I'm still figuring things out.

Ok here is my setup,

I have a MySqlDataAdapter filling a Dataset

The Dataset acts as the DataSource for a BindingSource

The BindingSource acts as the DataSource for a DataGridView

The DataGridView successfully displays the data! The data is a database of students at a martial arts school.

One of the columns is called "Belt Rank", I set this column up ahead of time to be a DataGridViewComboBoxColumn meaning it can take on any one of a predefined set of values, in this case the student's belt rank.

The values of this column can be:

White, Yellow, Green, Blue, Brown, Red, Black

What I want is to be able to sort the column by rank, rather then alphabetically.

I have searched the internet and have found no clear answer.

I know that DataGridView sorting is severely gimped by having a DataSource, however I dont know how to get around this.

I would greatly appreciate a clear explanation of how this can be achieved, or atleast a point in the direction of an explanation that wont make my head go "AHHHHHHHH!"

Thanks in advance!

Recommended Answers

All 7 Replies

What I find easier, but by no means proper, is to load a numerical column associated with the belt rank. You can hide the column and when the user wants to sort on belt you would really sort (under the hood) on the numeric column. You have to jump through a lot of hoops to implement grid sorting properly with microsoft's control.

Notice i'm actually sorting on the invisible BeltInt column, and you manually update the columns's header cell with a sort glyph so it appears that column is being sorted.

public enum Belts
    {
      Unknown = -1, //dont know how you want to handle this..
      White = 0, 
      Yellow = 1, 
      Green = 2, 
      Blue = 3, 
      Brown = 4, 
      Red = 5, 
      Black =6,
    }

    private void frmGridSorting_Load(object sender, EventArgs e)
    {
      
      dt = new DataTable();
      dt.Columns.Add(new DataColumn("Name", typeof(string)));
      dt.Columns.Add(new DataColumn("Belt", typeof(string)));
      dt.Columns.Add(new DataColumn("BeltInt", typeof(int)));
      dt.Rows.Add(new object[] { "Scott", Belts.White.ToString() });
      dt.Rows.Add(new object[] { "Adatapost", Belts.Black.ToString() });
      dt.Rows.Add(new object[] { "Danny", Belts.Green.ToString() });
      dataGridView1.DataSource = dt;
      dataGridView1.Columns["BeltInt"].Visible = false;
      Array.ForEach<DataRow>(dt.Rows.OfType<DataRow>().ToArray(), row =>
        {
          row["BeltInt"] = (int)Enum.Parse(typeof(Belts), Convert.ToString(row["Belt"]));
        });
    }

    private void button1_Click(object sender, EventArgs e)
    {
      if ((dataGridView1.Columns["Belt"].HeaderCell.SortGlyphDirection == SortOrder.None) ||
          (dataGridView1.Columns["Belt"].HeaderCell.SortGlyphDirection == SortOrder.Descending))
      {
        dataGridView1.Sort(dataGridView1.Columns["BeltInt"], ListSortDirection.Ascending);
        dataGridView1.Columns["Belt"].HeaderCell.SortGlyphDirection = SortOrder.Ascending;
      }
      else
      {
        dataGridView1.Sort(dataGridView1.Columns["BeltInt"], ListSortDirection.Descending);
        dataGridView1.Columns["Belt"].HeaderCell.SortGlyphDirection = SortOrder.Descending;
      }
    }

@Ramy Mahrous: What I got from that page is "The Sort(IComparer) method overload works only when the DataGridView control is not bound to an external data source and the VirtualMode property value is false. To customize sorting for columns bound to an external data source, you must use the sorting operations provided by the data source. In virtual mode, you must provide your own sorting operations for unbound columns."

The question I have then is how do I get my data source to sort with an Icomparer.

@sknake: Thanks for the tip, I might end up implementing a similar system if I find that I cannot get sort working using IComparer or something similar.

What you're after is the DataView Class.

Represents a databindable, customized view of a DataTable for sorting, filtering, searching, editing, and navigation.

Create a view from your datatable and bind to the view, instead of the table.

What you're after is the DataView Class.


Create a view from your datatable and bind to the view, instead of the table.

I attempted to implement this, yet dataview does not have any method of sorting using an IComparer either.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.