Reputation: 688
I have a DataGridView that is set to EditOnF2. I do some special processing of data in the CellEndEdit eventhandler that sets the value of the cell. I still want the functionality of the EditOnKeystrokeOrF2 of reverting to the original value when the Esc key is pressed. Unfortunately, at the CellEndEdit eventhandler, I don't see a way to tell what caused the CellEndEdit event to be fired. I only want to change the value of the cell if the Esc key is not pressed. How can I tell if it was or not?
Edit: It is worth noting that the KeyDown event does not get fired when the cell is being edited, nor for the final ending keystroke.
Edit2: I have tried the KeyPreview suggestion, but the form still does not capture the Escape key being pressed.
Edit3: I've been experimenting with trying to get this working. I originally posted some of the following as a separate post, but feel it might be more relevant to include it here.
I have a cell in a DataGridView that is now set to EditProgrammatically. To capture the keystroke that starts an edit, I am setting the cell.Value equal to the keystroke. However, this ruins the "Escape" functionality of the cell - when you press escape, instead of reverting to the original value, it reverts to the keystroke that I programmatically inserted into the cell.
I believe that if I could set the "EditedFormattedValue" on a cell, this would be where I want to put my keystroke value, however this appears to be read only. How can I accomplish what I am attempting?
An example to clarify: If the cell has a value of "54.3" in it, and I press the "9" key, it begins editing the cell and places a "9" there. If I hit Escape, instead of reverting to "54.3" it reverts to "9". What I want is for it to return to its original value of "54.3".
So, I am trying to tackle this issue from both the beginning and the end. I think the real problem is that I am overwriting the original value and have no way to determine if I should revert it or not.
Edit4: It looks like CellValidating might be worth using, but I am seeing strange behavior when I experiment with it. In a new project, I create the DataGridView and register for the various events and see that CellValidating is fired before the CellEndEdit. However, in my project where I am trying to get this to work, CellEndEdit is firing BEFORE CellValidating. Any ideas on what the difference might be?
Upvotes: 5
Views: 5271
Reputation: 4472
My problem was similar, Here is my workaround:
Problem:
When user started editing a cell value in DGV and pressed ESC key before committing value EndEdit was being called, which re-wrote all the DGV fields to database thus updating the update date & time fields, i only wanted DGV.EndEdit to run when user actually changed value and did not press ESC while doing so.
Solution:
In Cell Validation i used a flag like this to check if value is changed and if flag value is false the just do a if(!flag)return;
on EndEdit
Upvotes: 0
Reputation: 7925
First, you're absolutely right, KeyPreview
won't work. At first, I thought I could get around this by overriding the IsInputKey method of the form. This technique has worked for me in some other cases where I couldn't catch a key I needed to catch. That didn't work either, so I tried subclassing the DataGridView
and overriding IsInputKey
there. That didn't work either. After some digging through the other methods I could override, I learned there was another class of keys called command keys that I needed to intercept. To do that, override ProcessCmdKey on your DataGridView
(you'll need to subclass it).
Here is my code:
public class CommandKeyInterceptingDataGridView : DataGridView
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
Debug.WriteLine(keyData);
return base.ProcessCmdKey(ref msg, keyData);
}
}
And the output from entering edit mode with F2, modifying a cell to say "Hello" and canceling the edit with Escape.
F2
ShiftKey, Shift
H, Shift
E
L
L
O
Escape
Hopefully this gives you what you need.
Upvotes: 0
Reputation: 45117
Set the KeyPrevew property on your form to true; that will prevent the control from gobbling it up first. :)
Upvotes: 2