• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 563
  • Last Modified:

Setting DataGridView.CurrentCell is ignored or sets a row one less than clicked on...

Hi Guys,

I have some code that selects the row clicked on.  Previously it was called only on a right click in order to ensure that the correct row was selected before the context menu was updated and displayed, but now I need to ensure that the current row changes to prevent the wrong row data being dragged in drag and drop.  Here is the code:

        private void GridMouseDown(object sender, MouseEventArgs e)
        {
            // move cursor to clicked item
            DataGridView.HitTestInfo info = grid.HitTest(e.X, e.Y);
            if (info.Type == DataGridViewHitTestType.Cell)
            {
                grid.CurrentCell = grid[0, info.RowIndex];
            }
        }

Open in new window


At the click CurrentCell is 0,0.  Testing the value of info.RowIndex prior to setting CurrentCell shows 6.  After setting CurrentCell to [0,6]  the value of CurrentCell is [4,5]!!

Can anyone suggest why, and what to do about it?

Chris Bray
0
chrisbray
Asked:
chrisbray
  • 5
  • 3
1 Solution
 
khan_webguruCommented:
Make sure if it giving the row 6 but index will be 5 because that would be 0 base indexing. Means 0 is first row and 5 would be 6 then,
0
 
chrisbrayAuthor Commented:
Hi khan_webguru:

Thank you for your response - but unfortunately it does not seem to make sense.  If you look at the sample code, the row index is being retrieved from the HitTestInfo object which unsurprisingly returns the value zero based.

In any case, your response is spurious.  As described in the original question, when the data passed is [0,6] the current cell is set to [4,5].  I expect that when I set something to [0,6] it should result in [0,6] - not an unreasonable expectation I believe!!

Please can you revisit the question and try again?

Chris Bray
0
 
AndyAinscowCommented:
Have you checked that your row #7 (code snippet) is actually being run ?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
chrisbrayAuthor Commented:
Hi Andy,

Thanks for the question.  However, if I had not I would not have been able to give the results outlined in the original question, would I?

In the question I said

Testing the value of info.RowIndex prior to setting CurrentCell shows 6.  After setting CurrentCell to [0,6]  the value of CurrentCell is [4,5]!!

Given that the only place where CurrentCell is set is in line 7, it should be safe to assume that it had been run!!

Chris Bray
0
 
AndyAinscowCommented:
No.  You gave no indication of how you tested the current cell - in fact it looks like it is tested elsewhere in another code block.
The most obvious explanation of why does this code not work is that it isn't even run.

Have you tested it is run, not just assumed.  (Breakpoint).  Please confirm it is being run.
0
 
chrisbrayAuthor Commented:
Hi Andy,

At risk of repeating myself, YES!!  I had to test it to be able to give the results shown in the original question.  I even pointed out that I checked the values before and after setting the value, and reported those values.  

I am unsure how I could have made it any clearer...  however for the avoidance of doubt be advised that I manually stepped through the code block as shown, making tests on the values at each step.  The code that sets the value was indeed run, as it must have been since it is the ONLY place where the value is set and I could not have retrieved the values quoted in any other way.  After setting it to [0,6] in line seven (pressed F10 to move forward one step) I immediately tested the value of CurrentCell which returned [4,5].

I have also run additional tests to see whether hidden columns were the source of the problem (they are not, since Columns[0].Visible returns true).

However, I have now looked at the source code for the actual grid being used which t turns out inherits from DataGridView rather than being a framework control, and it seems that the base SetCurrentCellAddressCore method has been overridden to allow for hidden columns when moving using the keyboard.  I anticipate that I will find the cause in that code block...

I will keep you posted.

Chris Bray
0
 
chrisbrayAuthor Commented:
Hi Andy,

OK.  Found it...

The grid had been enhanced to prevent errors when using hidden columns and performing backward and forward movements within the grid.

SetCurrentCellAddressCore had been overridden, and if the change had not been made internally as a result of a mouse click checks were done to see whether the selection was being moved forwards or backwards:

 bool movingForward = CurrentCell.ColumnIndex < columnIndex;

Open in new window


This value was then used to calculate the next cell to land on If the requested next cell was in a hidden column.

The problem is that setting the CurrentCell property programmatically was treated as NOT having been done as a result of a mouse click, and therefore the fact that the passed columnIndex and CurrentCell.ColumnIndex were the same resulted in the assumption that the cursor was moving backwards.  Consequently CurrentCell was being set to the last column of the previous row.

The initial solution is two fold.  Firstly I have removed the external setter of the CurrentCell from the hosting form, and secondly I have made the assumption that any mouse down event would require the CurrentCell to be reset.

I have therefore modified the overridden OnMouseDown handler to automatically set the current cell including notification that this is happening as a result of a mouse click:

            HitTestInfo info = HitTest(e.X, e.Y);
            if (info.Type == DataGridViewHitTestType.Cell)
            {
                if (CurrentRow != null)
                {
                    SetSelectedRowCore(CurrentRow.Index, false);
                }

                SetSelectedRowCore(info.RowIndex, true);
                SetCurrentCellAddressCore(info.ColumnIndex, info.RowIndex, false, false, true);
            }

Open in new window


I want to do some further checks to see whether CellMouseDown would be more appropriate before I finalise the change, and I also want to look at handling the movement states in SetCurrentCellAddressCore to allow for moving forwards, moving backwards, or staying on the same column.  This should allow correct manual setting since I consider the existing code state to be a bug in that it should not consider staying in the same column to be a movement in any direction.

Chris Bray
0
 
AndyAinscowCommented:
Thanks for the update and glad to hear you sorted it out.
0
 
chrisbrayAuthor Commented:
I found the issue for myself.
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

  • 5
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now