472,811 Members | 1,798 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,811 software developers and data experts.

C# windows: DataGridView sorting event troubles

7,872 Expert 4TB
I am having trouble determining when my DataGridView object is sorting (based on a column header click).

The idea is, in a large table, sorting the columns takes time, so I show a splash screen. When it is done sorting I want the splash screen dissapear.

What I had been doing was using the CellClick and Sorted events:
Expand|Select|Wrap|Line Numbers
  1. private void myDGV_CellClick(object sender, DataGridViewCellEventArgs e)
  2. {
  3.    if (e.RowIndex == -1)
  4.    {//sorting
  5.       ShowSplash2(myDGV, "Sorting...");
  6.    }
  7. }
  9. private void myDGV_Sorted(object sender, EventArgs e)
  10. {
  11.    HideSplash2(myDGV);
  12. }
This works really well, except for one problem. On checkbox columns that all have the same value (or possibly columns that are "unsortable"?) The CellClick event is triggered, but the Sorted event is not triggered. No sorting operation happens, so the event never triggers?

Does anyone know of a better way to determine if the gridview is starting to sort? I looked at the SortCompare event, but it never seemed to be fired at all. (I think it only gets fired when you call the .Sort() function)

Problem 2)
When you click the top of a column to sort the data, all the cellstyles disapear. anyone know how to keep the cellstyling the same between row sorting?
Edit: Using the CellFormatting event and state data kept inside a hidden row, i can keep changing the row style based on it.
Oct 8 '08 #1
7 19777
190 Expert 100+
I've worked much with both sorting and the DataGridView, but that is a tricky question if you are not creating a subclassed DataGridView or BindingList, since most of the sorting related items are protected.
That said, let me throw out some ideas.

- First, easiest way to narrow down the cell-click problem would be to start the splash screen in the ColumnHeaderMouseClick event, since normal behavior is to only sort on ColumnHeader clicks.

- Second, is your DataSource a DataSet/DataTable or something else that implements IBindingList? If something else, is it your own extension of BindingList (most custom classes would need to extend BindingList in order to get sorting)? In which case, you could check for sorting from your BindingList/DataSource instead of the GridView...

- But assuming you are binding to a DataView (the underlying IBindingList of the DataSet) then what happens is on the left-click of the column header cell, if sorting is enabled, the Grid calls (IBindingList)DefaultView.ApplySort(PropertyDescri ptor[which is the column name], SortDirection [the sort glyph]);
Only once inside that method can you really be guaranteed the Grid is actually sorting. Unfortunately, as mentioned, it is a protected method, so you would have to have an entire BindingList implementation to get into that method and possibly raise a custom event or such.

I believe the SortCompare event is fired only when there is no underlying BindingList, and so the Grid literally compares each cell's text value, which would explain why it is not fired if you have any underlying binding source.

As far as the CellStyle changing goes...I find that odd. By default it should not change just because you have sorted. That said, there may be an obvious cause of it changing...but try to hunt down why...maybe even throw some debug lines into the CellStyleChanged event to see when and how. Although you found a workaround, at a high level it seems to me such a workaround should not be needed...unless you customized the CellFormatting event on the initial load, but somehow the same CellFormatting event is not getting called when you sort.

The CellFormatting event should really only be used as a last resort for customizations that cannot be cached in a DefaultCellStyle (and there are several...Grid, Row, Column, AlternatingRow) or its Format string.
Oct 10 '08 #2
190 Expert 100+
One more thought...the DataGridViewColumn has a SortMode property...which can be set to NotSortable for the columns such as all check boxes or whatnot...(assuming you truly do not want them sorted).

I guess the ColumnHeaderMouseClick would still be raised, but by setting that SortMode there would be no glyph there asking to be clicked.

Of course, this then begs the obvious and perhaps simplest solution...why not just check which column was clicked before firing off the splash screen...and not fire it for the columns which you have determined that ultimately do not fire a Grid.Sorted event...?
Oct 10 '08 #3
7,872 Expert 4TB
It was so much that I *didn't* want them sorted, as they just didn't sort. It doesn't matter to me if they do or do not, I jsut don't want them triggering the splash screen to come up, and then never having it go away. I just thought maybe I could watch the DataBindingComplete event, but that also is not fired for those columns.

Yes, I set the DataSource to a DataTable, you're saying there is something in there I can watch for the sorting?

I didn't use the ColumnHeaderMouseClick because the event appeared to fire AFTER the sorting was done, as opposed to the regular cellclick which appeared to happen before the sorting.

As for not picking specific columns, I may have to do that. I had hoped to keep this genereic and as free from preprocessing as possible
Oct 10 '08 #4
190 Expert 100+
I did not notice you were checking the RowIndex during the cell click, so you are already filtering on the ColumnHeader row, making my suggestion about ColumnHeaderMouseClick irrelevant...sorry.

I think you could do this with a minimum of 'extra' code. The suggestion of subclassing a BindingList would be way overkill if you want to keep it simple. [All I was suggesting about DataTable is that when it sorts, the Grid casts the DataSet to IBindingList and calls ApplySort on it...so IF you could override that method, you would be guaranteed to know sorting was happening...but you would have to implement your own BindingList to do so...]

You are already checking the row, so why not check the column on the CellClick event as well. I could see two possibilites:

1. Assume you only want TextBoxCell columns sorted (not Button, CheckBox, Image or Link). You could simple check the CellType or CellTemplate property of the column before firing the splash screen.

2. Set the SortMode of each column (it's a public property, so I would consider that minimal code interference) at initialization, and then at CellClick get the column and only fire the splash screen for columns that are not NotSortable.
Oct 10 '08 #5
7,872 Expert 4TB
Well after your recent suggestions I think I have a good enough solutions for it:
Expand|Select|Wrap|Line Numbers
  1. private void dgvResults_CellClick(object sender, DataGridViewCellEventArgs e)
  2. {
  3.    if ((e.RowIndex == -1)&&(e.ColumnIndex!=-1))//if both -1, it is the "select all" corner
  4.    {
  5.       if (dgvResults.Columns[e.ColumnIndex].CellType == typeof(DataGridViewTextBoxCell))
  6.       {//sorting
  7.          ShowSplash2(dgvResults, "Sorting...");
  8.       }
  9.    }
  10. }
Thanks for the help on that.

As for the cellformating, I stopped looking into it when I found the cellformating event, lets me supply dynamic cell formating based on cell contents.

As a side note, it was the DefaultCellStyle proeprty of the row that I was setting, that was getting reset durring a column sort
Oct 10 '08 #6
Sample code :
Expand|Select|Wrap|Line Numbers
  1. string Connstring = @"Server=IN44109369\SQLExpress; Database=MATool;Trusted_Connection=Yes";
  2.         conn = new SqlConnection(Connstring);
  3.         string SQLcnn = "SELECT Id,Analyst,VendorType,Site,Legal,QAD_Code,Phase_II_Audit,QAD_Status,Code_Status,Pop_Form_TAT,Rec_Form_TAT,TAT_AP,EDI_TAT,VMTAT,Audited_By,VM_FTT,TOE,VM_Error_Desc,Category,Fatal,Non_Fatal,PhaseII_AuditStatus,Audit_Status,Audit_Compl_Date,Audit_Compl_Time,Audit_TAT FROM [dbo].[tblQAD] where [Audited_By]= @PAnalyst and [PhaseII_AuditStatus] = @PStatus";
  4.         cmd = new SqlCommand(SQLcnn, conn);
  5.         cmd.Parameters.Add(new SqlParameter("@PAnalyst", System.Data.SqlDbType.NChar, 10, "Audited_By"));
  6.         cmd.Parameters.Add(new SqlParameter("@PStatus", System.Data.SqlDbType.NChar, 10, "PhaseII_AuditStatus"));
  7.         cmd.Parameters["@PAnalyst"].Value = lblUser.Text;
  8.         cmd.Parameters["@PStatus"].Value = lblPendingStatus.Text;
  9.         SqlDataAdapter sdr = new SqlDataAdapter(cmd);
  10.         DataTable dt = new DataTable("tblQAD");
  11.         sdr.Fill(dt);
  12.         int dataTableRowCount = dt.Rows.Count;
  13.         if (dataTableRowCount > 0)
  14.         {
  15.             GridView1.Visible = true;
  16.             GridView1.DataSource = dt;
  17.             GridView1.DataBind();
  18.         }
  19.         else
  20.         {
  21.             GridView1.Visible = false;
  22.         }
  24. private string GetSortDirection()
  25.     {
  26.         switch (GridViewSortDirection)
  27.         {
  28.             case "ASC":
  29.                 GridViewSortDirection = "DESC";
  30.                 break;
  32.             case "DESC":
  33.                 GridViewSortDirection = "ASC";
  34.                 break;
  35.         }
  37.         return GridViewSortDirection;
  38.     }
  39.     private string GridViewSortDirection
  40.     {
  41.         get { return ViewState["SortDirection"] as string ?? "ASC"; }
  42.         set { ViewState["SortDirection"] = value; }
  43.     }
  44.     private string GridViewSortExpression
  45.     {
  46.         get { return ViewState["SortExpression"] as string ?? string.Empty; }
  47.         set { ViewState["SortExpression"] = value; }
  48.     }
  50.     private string ConvertSortDirectionToSql(SortDirection sortDirection)
  51.     {
  52.         string newSortDirection = String.Empty;
  54.         switch (sortDirection)
  55.         {
  56.             case SortDirection.Ascending:
  57.                 newSortDirection = "ASC";
  58.                 break;
  60.             case SortDirection.Descending:
  61.                 newSortDirection = "DESC";
  62.                 break;
  63.         }
  65.         return newSortDirection;
  66.     }
  69.     protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
  70.     {
  71.         GridView1.EditIndex = -1;
  72.         GridView1.PageIndex = e.NewPageIndex;
  73.         GridView1.DataSource = SortDataTable(GridView1.DataSource as DataTable, true);
  74.         GridView1.DataBind();
  75.     }
  77.     protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
  78.     {
  79.         GridViewSortExpression = e.SortExpression;
  80.         int pageIndex = GridView1.PageIndex;
  81.         GridView1.DataSource = SortDataTable(GridView1.DataSource as DataTable, false);
  82.         GridView1.DataBind();
  83.         GridView1.PageIndex = pageIndex;
  84.     }
  85.     protected DataView SortDataTable(DataTable dataTable, bool isPageIndexChanging)
  86.     {
  87.         if (dataTable != null)
  88.         {
  89.             DataView dataView = new DataView(dataTable);
  90.             if (GridViewSortExpression != string.Empty)
  91.             {
  92.                 if (isPageIndexChanging)
  93.                 {
  94.                     dataView.Sort = string.Format("{0} {1}", GridViewSortExpression, GridViewSortDirection);
  95.                 }
  96.                 else
  97.                 {
  98.                     dataView.Sort = string.Format("{0} {1}", GridViewSortExpression, GetSortDirection());
  99.                 }
  100.             }
  101.             return dataView;
  102.         }
  103.         else
  104.         {
  105.             return new DataView();
  106.         }
  107.     }
  108.     public override void VerifyRenderingInServerForm(Control control)
  109.     {
  110.         // Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
  111.     }
Well after your recent suggestions I think I have a good enough solutions for it:
Expand|Select|Wrap|Line Numbers
  1. private void dgvResults_CellClick(object sender, DataGridViewCellEventArgs e)
  2. {
  3.    if ((e.RowIndex == -1)&&(e.ColumnIndex!=-1))//if both -1, it is the "select all" corner
  4.    {
  5.       if (dgvResults.Columns[e.ColumnIndex].CellType == typeof(DataGridViewTextBoxCell))
  6.       {//sorting
  7.          ShowSplash2(dgvResults, "Sorting...");
  8.       }
  9.    }
  10. }
Thanks for the help on that.

As for the cellformating, I stopped looking into it when I found the cellformating event, lets me supply dynamic cell formating based on cell contents.

As a side note, it was the DefaultCellStyle proeprty of the row that I was setting, that was getting reset durring a column sort
Oct 22 '08 #7
7,872 Expert 4TB
Hmm it would seem *I* am guilty of not following proper question titles, I should have stated clearly that I was using a windows application, not a web application.
I will edit the question title
Oct 23 '08 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

by: msmith | last post by:
When I try to add this event handler, I get an error: this.dgScheduleCamera.UserAddedRow += new System.Windows.Forms.DataGridViewRowEventHandler(this.dgScheduleCamera_UserAddedRow); Error: No...
by: scotch.yard | last post by:
Hi, I filled a DataGridView with some data and then changed some cells format in order to separate them by content. For example, city names are blue, numbers are green, some words are in...
by: Simon Harvey | last post by:
Hi Guys, Can anyone tell me why the DataGridView.SelectionChanged event fires twice when I databind to it. If I do the following, the first row is selected automatically, but the changed...
by: =?Utf-8?B?U2hhcm9u?= | last post by:
I'm using a DataGridView on a Form. I want to disable the clicking on the columns headers to disallow the sorting. How can I do that, but without deriving the DataGridView? Is there any other...
by: harikap | last post by:
hi , here im using vb.net 2005how can i add radiobuttons as column to windows datagridview control plz help me....
by: systeko | last post by:
Hello, I have one little problem which make me crazy. I've made application (for Windows) in Visual C#. On one panel I've got datagridview control which is not bind to database, I populate it...
by: Queez | last post by:
OK, this is rediculous... Surely, sorting should be one of the easiest things with the ASP.NET DataGridView control. I mean, there's hundreds of sites out there (Microsoft MSDN entries included)...
by: Frinavale | last post by:
I have implemented the ITemplate interface to dynamically "display" complicated data in a GridView. For the life of me I cannot implement the template in such a way that when it is applied to...
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 2 August 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.