none
DatagridView exception at sorting "Current cell cannot be set to an invisible cell."

    Question

  • Hi All,

    I have a datagridview where I want to hide a few rows depending on a filter. (The data source is a Linq to SQL query.)

     

    When I hide the rows I set them to invisible. It is working fine, but when I click on one of the Column header to short the table it throws an exception.

    I think it happens because the first row after sort is invisible.

    What should I do differently to avoid this exception?

    The exception:

     

    System.InvalidOperationException occurred
     Message="Current cell cannot be set to an invisible cell."
     Source="System.Windows.Forms"
     StackTrace:
      at System.Windows.Forms.DataGridView.SetCurrentCellAddressCore(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick)
      at System.Windows.Forms.DataGridView.SetAndSelectCurrentCellAddress(Int32 columnIndex, Int32 rowIndex, Boolean setAnchorCellAddress, Boolean validateCurrentCell, Boolean throughMouseClick, Boolean clearSelection, Boolean forceCurrentCellSelection)
      at System.Windows.Forms.DataGridView.SortInternal(IComparer comparer, DataGridViewColumn dataGridViewColumn, ListSortDirection direction)
      at System.Windows.Forms.DataGridView.OnColumnHeaderMouseClick(DataGridViewCellMouseEventArgs e)
      at System.Windows.Forms.DataGridView.OnMouseClick(MouseEventArgs e)
      at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
      at System.Windows.Forms.Control.WndProc(Message& m)
      at System.Windows.Forms.DataGridView.WndProc(Message& m)
      at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
      at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
      at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
      at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
      at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
      at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    
    

     


    The code where I hide the rows:

     

       this.SuspendLayout();
    
       foreach (DataGridViewRow row in dgvPipeline.Rows)
       {
        if (chkShowCancelled.Checked || row.Cells[dgvcStatus.Index].FormattedValue.ToString() != "Cancelled")
        {
         row.Visible = true;
        }
        else
        {
         row.Visible = false;
        }
       }
    
       this.ResumeLayout();
    
    

     


    I have also tried to set the current cell after hiding the rows:

     

       this.SuspendLayout();
    
       DataGridViewRow firstVisibleRow = null;
    
       foreach (DataGridViewRow row in dgvPipeline.Rows)
       {
        if (chkShowCancelled.Checked || row.Cells[dgvcStatus.Index].FormattedValue.ToString() != "Cancelled")
        {
         if (firstVisibleRow == null)
         {
          firstVisibleRow = row;
         }
    
         row.Visible = true;
        }
        else
        {
         row.Visible = false;
        }
       }
    
       dgvPipeline.CurrentCell = firstVisibleRow.Cells[dgvcExpected.Index];
    
       this.ResumeLayout();
    

     


    Somewhere I read the rows should be hidden like this (but it did not work either):

     

       CurrencyManager cm = (CurrencyManager)dgvPipeline.BindingContext[dgvPipeline.DataSource];
    
       cm.SuspendBinding();
    
       foreach (DataGridViewRow row in dgvPipeline.Rows)
       {
        if (chkShowCancelled.Checked || row.Cells[dgvcStatus.Index].FormattedValue.ToString() != "Cancelled")
        {
         row.Visible = true;
        }
        else
        {
         row.Visible = false;
        }
       }
    
       cm.ResumeBinding();
    

     


    Any other tricks/tips to solve this issue?

    Thanks for your help in advance.

     

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    Wednesday, July 13, 2011 10:12 AM

Answers

  • Hi Neddy,

     

    You are right, I don't think hiding the rows is a good solution either. On the other hand this is very weird for me to have an option like this (set a row to invisible) and it is not recommended to use, because it is not really working... :)

     

    I have checked your first link where the solution is to use some third party thingy (CSLA.NET). I have never heard about it. I will check it, thanks.

     

    The next two link is about filtering the data source itself...

    This is my solution too, with a little change. In my case, to get the data from the database takes relatively too much time, so I query the whole list, convert it to a List and filter the result list based on the filters. In this way when the filters are changed the data data will be not queried again just the List will be filtered. This makes the filtering fast and the rows can be sorted without exceptions.

     

    So, to summarize this issue:

     - I mustn't set rows to invisible in a datagridview, because it has bugs

     - I cannot use the datagridview filter as it is not implemented for the linq query results

     - I should filter the data source or use a thirdparty stuff

     

    Thanks for your help.

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by Crick3t Tuesday, July 19, 2011 8:33 AM
    Tuesday, July 19, 2011 8:32 AM

All replies

  • Ok, I have tried many other things like this:

    http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.currentcell.aspx

    private void dataGridView1_Sorted(object sender, EventArgs e)
    {
      this.dataGridView1.FirstDisplayedCell = this.dataGridView1.CurrentCell;
    }
    
    


    But it is not working as my datagridview is bounded. (I have tried with other cells, null, etc.)

    I have tried to subscribe on all of the events that I can find and set the CurrentCell and FirstDisplayedCell.

    Nothing worked...

     

    So, I changed the whole code and now instead of set the visible property of the row to false I am filtering the data source.

    Currently it is working, but not as fast as the original one.

     

    We can say this is a solution or a workaround.

     

    If anyone has any other solution then please let me know.


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    Wednesday, July 13, 2011 4:35 PM
  • Hi Peter,

    Welcome to the MSDN Forum.

    Based on your descriptions,  use BindingSource.Filter is a good way to filter the data. Here are the resolved threads which has talked such issue:

    [Thread]How to sort rows in dataset?
    http://social.msdn.microsoft.com/Forums/en/winforms/thread/6cb1bd06-2c4a-4fb4-8188-d15308aeb5a5

    [Thread]BindingSource.filter like digraphs, trigraphs:
    http://social.msdn.microsoft.com/Forums/en-IE/winformsdatacontrols/thread/a27f6160-3c28-4ab6-b0fd-cfd62433fe9c

    In the second thread, I've provided the sample project, you can download it and run it which is developed by using the Visual Studio 2008.

    If you have any questions, please feel free to tell us.

    Best Regards


    Neddy Ren [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, July 18, 2011 6:53 AM
  • Hi Neddy,

    Thanks for the tip.

    I thought about the Filter property of the binding source too, but in my case the underlying data source is a Linq to SQL query and I think it is not implementing the IBindingListView interface.

    Regarding to the msdn: " Only underlying lists that implement the IBindingListView interface support filtering."

    http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.filter.aspx

     

    And the "SupportsFiltering" property of the binding source is false.

     

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.

    Monday, July 18, 2011 12:53 PM
  • Hi Neddy,

    Thanks for the tip.

    I thought about the Filter property of the binding source too, but in my case the underlying data source is a Linq to SQL query and I think it is not implementing the IBindingListView interface.

    Regarding to the msdn: " Only underlying lists that implement the IBindingListView interface support filtering."

    http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.filter.aspx 

    And the "SupportsFiltering" property of the binding source is false. 


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.

    Hi Circk3t,

    Sorry, it is the Linq-to-SQL. The issue has been resoved at the following thread:

    http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/58e32c13-b414-45e1-a449-6acd5854fc92/

    I don't think hide the row in the DataGridView is a good way. Or you can use other ways to achieve your target as:

    How to: Filter Related Data (LINQ to SQL):
    http://msdn.microsoft.com/en-us/library/bb882678.aspx

    How to: Filter at the DataContext Level (LINQ to SQL):
    http://msdn.microsoft.com/en-us/library/bb386915.aspx

    If you have any questions, please feel free to tell us.

    Best  Regards

     



    Neddy Ren [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, July 19, 2011 6:23 AM
  • Hi Neddy,

     

    You are right, I don't think hiding the rows is a good solution either. On the other hand this is very weird for me to have an option like this (set a row to invisible) and it is not recommended to use, because it is not really working... :)

     

    I have checked your first link where the solution is to use some third party thingy (CSLA.NET). I have never heard about it. I will check it, thanks.

     

    The next two link is about filtering the data source itself...

    This is my solution too, with a little change. In my case, to get the data from the database takes relatively too much time, so I query the whole list, convert it to a List and filter the result list based on the filters. In this way when the filters are changed the data data will be not queried again just the List will be filtered. This makes the filtering fast and the rows can be sorted without exceptions.

     

    So, to summarize this issue:

     - I mustn't set rows to invisible in a datagridview, because it has bugs

     - I cannot use the datagridview filter as it is not implemented for the linq query results

     - I should filter the data source or use a thirdparty stuff

     

    Thanks for your help.

     


    Regards, Peter

    //If a post answers your question, please click "Mark As Answer".
    //Also if a post seems to be helpful, please click "Mark as Helpful" on that post.
    • Marked as answer by Crick3t Tuesday, July 19, 2011 8:33 AM
    Tuesday, July 19, 2011 8:32 AM