473,405 Members | 2,334 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

C# windows: DataGridView sorting event troubles

Plater
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. }
  8.  
  9. private void myDGV_Sorted(object sender, EventArgs e)
  10. {
  11.    HideSplash2(myDGV);
  12. }
  13.  
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 19930
mldisibio
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
mldisibio
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
Plater
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
mldisibio
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
Plater
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. }
  11.  
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.         }
  23.  
  24. private string GetSortDirection()
  25.     {
  26.         switch (GridViewSortDirection)
  27.         {
  28.             case "ASC":
  29.                 GridViewSortDirection = "DESC";
  30.                 break;
  31.  
  32.             case "DESC":
  33.                 GridViewSortDirection = "ASC";
  34.                 break;
  35.         }
  36.  
  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.     }
  49.  
  50.     private string ConvertSortDirectionToSql(SortDirection sortDirection)
  51.     {
  52.         string newSortDirection = String.Empty;
  53.  
  54.         switch (sortDirection)
  55.         {
  56.             case SortDirection.Ascending:
  57.                 newSortDirection = "ASC";
  58.                 break;
  59.  
  60.             case SortDirection.Descending:
  61.                 newSortDirection = "DESC";
  62.                 break;
  63.         }
  64.  
  65.         return newSortDirection;
  66.     }
  67.  
  68.  
  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.     }
  76.  
  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.     }
  112.  
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. }
  11.  
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
Plater
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

2
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...
0
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...
2
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...
1
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...
7
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....
0
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...
0
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)...
3
Frinavale
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...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.