If I press and hold down either the UP or DOWN arrow key when focused on a DataGridView, the cursor (blue highlighted cell) doesn't move evenly down the rows, instead it jumps several rows at a time in batches. Sometimes it doesn't even seem to move at all until the key is finally released, then the cursor jumps directly to several rows ahead having presumably stored all the key presses.
Here is a GIF image showing the behaviour when pressing and holding the DOWN arrow, then releasing it and pressing and holding the UP arrow.
This movement looks wrong and makes it hard for the user to judge when to release the key to navigate smoothly over several rows. It doesn't even seem to move an number of rows on each jump it makes (like 10-20 rows on each jump, sometimes the whole page, or even reappearing many rows beyond when the user finally releases the key).
For example if the user wants to move the cursor about half way down the page, by pressing the DOWN arrow key and holding it down, then it is very hard to know when to release the key because the cursor is not moving down in an even progress.
Why doesn't it visibly move to each row one at a time in a smooth repeating manner, instead of doing ugly hopping over batches of rows?
This can be reproduced as follows:
Make a new forms project.
Drop a DataGridView control onto the form.
Add a DataGridViewTextBoxColumn in the designer.
Add some rows to the DataGridView, and add a little formatting to make enough rows visible for your test, in the FormLoad event:
private void Form1_Load(object sender, EventArgs e)
{
dataGridView1.RowTemplate.Height = 14;
dataGridView1.Rows.Add(50);
dataGridView1.Dock = DockStyle.Fill;
}
Then run the program and press and hold the DOWN arrow key to see how the blue highlight jumps down strangely instead of moving smoothly down from row to row.
The strange behaviour exists even when the DataGridView is read only.
I have tried making the grid and the form DoubleBuffered but no success. I have also tried setting the grid to Virtual mode and ReadOnly and changing just about every setting of the grid, but nothing works.
The only way I have discovered to make the cursor to move smoothly and rapidly up or down the rows without jumping over batches of rows, has been to not let the DataGridView be focused. To do this I make another control on the form (for example a textbox, and give focus to the text Box). Then I override the processCmdKey method on the form to capture the keyboard input and if it detects an arrow key then I programmatically change the current cell in the DataGridView (for example to the next row if the DOWN key was detected in processCmdKey). This moves the current cell without ever giving actual focus to the DataGridView. The movement of the highlight then appears to progress evenly and doesn't jump down in strange batches.
Add a text box onto the form
Add this code to the form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
int currentRowIndex = dataGridView1.CurrentCell.RowIndex;
switch (keyData)
{
case Keys.Up:
// Check not already at the first row in the grid before moving up one row
if (currentRowIndex > 0)
dataGridView1.CurrentCell = dataGridView1.Rows[currentRowIndex - 1].Cells[dataGridView1.CurrentCell.ColumnIndex];
return true;
case Keys.Down:
// Check not already at the last row in the grid before moving down one row
if (currentRowIndex + 1 < dataGridView1.Rows.Count)
dataGridView1.CurrentCell = dataGridView1.Rows[currentRowIndex + 1].Cells[dataGridView1.CurrentCell.ColumnIndex];
return true;
}
// Line below is reached if we didn't handle the key in this method, it tells the form/control to handle it
return base.ProcessCmdKey(ref msg, keyData);
}
Then run the program to test again as follows:
Click on the text box to give it focus (instead of the grid). Then press and hold the DOWN key, to see that the blue highlighted current cell progresses smoothly down through the rows. Release the key.
Then click on the grid to give it focus, then press and hold the UP or DOWN arrow key and witness the blue highlight jumping across several rows instead of progressing smoothly.
So the problem exists whenever the DataGridView has focus, regardless of whether the grid handles the keys presses or if I handle them in processCmdKey.
I don't want to rely of keeping focus away from the grid, because there are times when a grid needs to have focus. I'd also have to add a lot more code to processCmdKey to handle all the other potential key presses for a grid, such as tab, page up / down, enter etc., which doesn't seem sensible.
The grid will actually be read only in my application, so it is probably only really the ability to move around smoothly that I need to use, but nevertheless having a dummy control that is focussed instead of the grid doesn't seem sensible.
A slightly similar problem was mentioned here (DataGrid not scrolling smoothly), but it is not Windows Forms and the original poster seemed to state that his problem was fixed by getting rid of all event handling and turning on virtualization, but I've tried virtual mode and I am not handling any events of the grid. He also states that he was on a very busy server. So I think this probably merits me adding this as its own separate question.
Any help would be much appreciated. Thanks :)
The problem has now been solved by changing the keyboard repeat speed settings on the computer. I went to Control Panel | Ease of Access | Change How Your Keyboard Works | Scroll down and choose 'See also: Keyboard Settings'. This then displays a window called 'Keyboard Properties', where I had to lower the 'Repeat Rate', I moved the slider slightly form Maximum (about a quarter of the way from maximum) and clicked apply.
The when I re-tested the program, it worked normally and the cursor moved smoothly down the grid when I pressed and held the Down arrow key.
So I am guessing that there is something strange about my PC that made it not able to cope well when using the maximum keyboard repeat rate, in the case of a DataGridView.
In an ideal world, I'd be able to use a really fast keyboard repeat rate set to maximum, but I am happy enough to settle for a slower keyboard repeat rate in order to solve my problem using the arrow keys smoothly on a DataGridView.
#Sinatr, thanks again for helping me by testing the code on your PC, just telling me that you couldn't reproduce it and that I probably had a problem with my PC rather than my code, was a big help.
I'm converting a reaction time test to tablet PC. The test involves the user pressing the 5 key on the numeric keypad and holding it down until a random timer fires off and gives them a direction stimulus. They are then supposed to release the key and press the corresponding direction key (8, 4, 6, 2) and then return to pressing and holding the 5 key.
The problem I'm having is that the tablet treats a long press or press and hold as a right click. I need to be able to override this behavior. If I put a button on the form with a mousedown and mouseup event, the mousedown event fires properly if I tap-taphold, and then mouseup fires when I release. but I need a similar event to mousedown for a long press that isn't preparing the tablet for right click.
Any ideas?
Assuming you are using WinRT-XAML and not WPF, Silverlight or Windows Forms - you could use the PointerPressed/PointerReleased events instead of the click or gesture events.
"Resolved", Thanks for input
i cant figure this out.
After i press the keyboard (With or without attatching event handlers for keystrokes)
MouseEvents gets blocked for a short period of time.
-Modifier keys does not block the mouse events (ctrl, shift...)
So what happends is, if i press like 'A', and press the mouse on some control, it does not register. (It takes somewhere between 500ms to 1s for the mouseclicks to register again)
Anyone else experienced this? Is there a workaround?
Iv tried hooking onto PreviewKeyDown and Up on all my contols/windows and done e.Handled = true, but no luck.
Kind Regards Tor Einar
I am trying to make buttons seem like pressed automatically so the user can then follow the buttons pressed but everytime I try it doesn't seem natural because the computer does it really fast all the changes!
Any ideas? I have to get a serious of buttons pressed that look like user pressed and then pass to unpressed again
Thanks a lot!!!!
Well I'm trying to make a game where you remember the buttons that were randomly selected by the computer and then you press them, so I need computer to act like if the user were touching them and then the user follows...
How about using a custom storyboard animation that takes the button to the pressed, and then unpressed state?
I am making one "keyboard operated application" in which the user will use only keyboard.
The user will use left and right arrow keys, sometimes Up and Down arrow keys to navigate through different controls while filling a form.For that I use the keydown event and use SendKeys.SendWait({TAB}) for right key and SendKeys.SendWait(+{TAB}) for left key.
I have one DateTimePicker with custome format of dd/MM/yyyy.
When the year part is selected and the user presses the left arrow key, the focus moves to month part. when the arrow key is again pressed the focus moves to day part.
What I want is that when the day part is selected and the user presses the left arrow key, focus should move to the previous control (SendKeys.SendWait(+{TAB})).
Please suggest a solution.
Edit: The standard DateTimePicker does not expose any way to tell what element is selected, unfortunately, so it isn't possible to achieve this without creating your own control.