Click here to Skip to main content
15,906,081 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm working on a C# winForm project that uses a dataGridView. I've created a "customRowDivider" that I'm using to separate my dataGridView into categories. For example a grid with 1 column and 10 rows may list the first 6 rows as vehicles, the next 2 rows as owners and the last 2 rows as dealerships. I insert a "customRowDivider" between each category. What I'd like to do is implement my own custom sort that will sort according to "each" category and not according to the entire grid. Can someone please point me in the right direction on how to go about this?

public class Form1 : Form
{
   Dictionary<int, CustomRowDivider > rowDivs;
   RowDivider rowDiv;
   DataGridViewRow row;

   public Form1()
   {
       grid.Columns.Add("colName", "Name");
       grid.Columns["colName"].SortMode = DataGridViewColumnSortMode.Programmatic;
       grid.ColumnHeaderMouseClick += grid_ColumnHeaderMouseClick;

       row = new DataGridViewRow();
       DataGridViewTextBoxCell cell1 = new DataGridViewTextBoxCell();
       cell1.Value = "ScrewDriver";
       row.Cells.Add(cell1);
       grid.Rows.Add(row);

       row = new DataGridViewRow();
       DataGridViewTextBoxCell cell2 = new DataGridViewTextBoxCell();
       cell2.Value = "Nails";
       row.Cells.Add(cell2);
       grid.Rows.Add(row);

       row = new DataGridViewRow();
       DataGridViewTextBoxCell cell3 = new DataGridViewTextBoxCell();
       cell3.Value = "Wood";
       row.Cells.Add(cell3);
       grid.Rows.Add(row);
       
       rowDiv = new RowDiv(3);
       rowDivs.Add(0, rowDiv);
       grid.Rows.Add(rowDiv);

       row = new DataGridViewRow();
       DataGridViewTextBoxCell cell4 = new DataGridViewTextBoxCell();
       cell4.Value = "Buick";
       row.Cells.Add(cell4);
       grid.Rows.Add(row);

       row = new DataGridViewRow();
       DataGridViewTextBoxCell cell5 = new DataGridViewTextBoxCell();
       cell5.Value = "Ford";
       row.Cells.Add(cell5);
       grid.Rows.Add(row);

       // etc...
   }

    // this is where i'd like to sort at...
    private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
    {
         for (int i = 0; i > grid.Rows.Count; i++)
         {
               // stop and sort once I reach a rowDivider
               if(grid.Rows[i] is CustomRowDivider)
               {
               }
               else
               {
               }
         }
     }
}
 
public class CustomRowDivider : DataGridViewRow
{
  public int Idx;
  
  public CustomRowDivider() {}

  public CustomRowDivider(int idx)
         :base()
  {
       Idx = idx;
       base.Height = 3;
       base.DefaultCellStyle.BackColor = Color.LightGray;
  }
}
Posted
Updated 15-May-13 8:50am
v3
Comments
Maciej Los 15-May-13 14:09pm    
Does your gridview is bind with datasource?
d.allen101 15-May-13 14:14pm    
no it's an unbound grid
Maciej Los 15-May-13 14:37pm    
So... If you have only one column, how do you recognize that that single record belongs to one of the category: vehicles, owners, dealerships?
At this moent i can suggest you to use List<t>[^] generic class, which provide functionality for sort (and many others).
d.allen101 15-May-13 14:42pm    
because each row is contained within its own category which separated by the rowDivider
Maciej Los 15-May-13 14:54pm    
Please, use "Reply" widget.

Does RowDivider contains any data?

1 solution

A possible solution is that you group your data collection by category and sort the items. After that you fill the datagridview with the result.

If you have problems with reading the code I will do it smaller for you.



C#
public partial class Form1 : Form
    {
        List<KeyValuePair<KeyValuePair<string, SortDirection>, string>> data = new List<KeyValuePair<KeyValuePair<string, SortDirection>, string>>();

        public Form1()
        {
            InitializeComponent();

            this.Load += Form1_Load;
        }

        void Form1_Load(object sender, EventArgs e)
        {
            this.dataGridView1.Columns.Add("colName", "Name");
            this.dataGridView1.Columns["colName"].SortMode = DataGridViewColumnSortMode.Programmatic;

            // Key => Category which describe every block
            // Value => Speaks for itself
            KeyValuePair<string, SortDirection> cat1 = new KeyValuePair<string,SortDirection>("Block 1", SortDirection.ASC);
            KeyValuePair<string, SortDirection> cat2 = new KeyValuePair<string,SortDirection>("Block 2", SortDirection.DESC);

            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat1, "c"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat1, "a"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat1, "d"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat1, "b"));

            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat2, "c"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat2, "a"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat2, "d"));
            data.Add(new KeyValuePair<KeyValuePair<string, SortDirection>, string>(cat2, "b"));
            
            // Group the items by category
            var groupedByCategoryAndSorted = data.GroupBy(x => x.Key);

            
            foreach (var category in groupedByCategoryAndSorted)
            {
                // add the category to datagrid as RowDivider item
                CustomRowDivider rowDiv = new CustomRowDivider(category.Key.Value);

                this.dataGridView1.Rows.Add(rowDiv);


                IOrderedEnumerable<KeyValuePair<KeyValuePair<string, SortDirection>, string>> sortedItems;

                if (rowDiv.SortDirection == SortDirection.ASC)
                {
                    sortedItems = category.OrderBy(x => x.Value);
                }
                else
                {
                    sortedItems = category.OrderByDescending(x => x.Value);
                }

                // enumerate the sorted list
                for (int i = 0; i < sortedItems.Count(); i++)
                {
                    var currentItem = sortedItems.ElementAt(i);

                    // Add the items to datagrid
                    var row = new DataGridViewRow();
                    DataGridViewTextBoxCell cell1 = new DataGridViewTextBoxCell();
                    cell1.Value = currentItem.Value;
                    row.Cells.Add(cell1);
                    this.dataGridView1.Rows.Add(row);
                }
            }
        }
    }

    public class CustomRowDivider : DataGridViewRow
    {
        public int Idx;

        public CustomRowDivider() { }

        public CustomRowDivider(SortDirection direction)
            : base()
        {
            this.SortDirection = direction;
            base.Height = 10;
            base.DefaultCellStyle.BackColor = Color.LightGray;
        }

        public SortDirection SortDirection { get; private set; }
    }

    public enum SortDirection
    { 
        ASC,
        DESC
    }



Result in datagridview will be:
RowDivider
a
b
c
d
RowDivider
d
c
b
a
 
Share this answer
 
v4
Comments
d.allen101 15-May-13 16:08pm    
This is exactly what I'm trying to accomplish! This is good code! It's a little above my head but I think I can go from here. I don't mind Google what I don't understand. Thanks David! If I have any questions which I'm sure I will I post additional comments but I want to take over from here and give it a try...Thanks again!
d.allen101 15-May-13 16:09pm    
Hey I was going to accept this as the solution but if I do won't it close this thread? I don't want to close the thread just in case if I get stuck somewhere and need to reach out
Richard C Bishop 15-May-13 16:33pm    
FYI, the thread does not close, it is just moved to the answered list instead of unanswered. It remains available for all to search.
d.allen101 15-May-13 16:37pm    
ok thx!
David Melcher 15-May-13 16:10pm    
You're welcome :) please mark the post as solution of your problem. Happy coding

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