Hello @ChuckieAJ ,
When a user clicks or tabs into a property's value field, the grid creates an in-place active inline editor (such as a text box or combo box). Since this internal control captures keyboard inputs for text traversal, the arrow keys will move the text cursor left, right, up, or down within the text itself. Consequently, these keys are consumed and cannot be used to navigate between different grid rows.
From a standard Windows UX perspective, it is generally recommended to stick to the default behavior. Users can simply press Enter (to commit changes) or Esc (to cancel their input) to exit the edit mode. Once exited, the grid regains focus, and the Up/Down arrow keys will navigate through the property rows as expected.
If your project requirements specifically dictate that the arrow keys should move to the next/previous property seamlessly, even while the user is actively typing, you could consider a workaround.
You can accomplish this by deriving a custom class from CMFCPropertyGridCtrl and overriding its PreTranslateMessage function. This approach intercepts the arrow key presses, manually ends the edit session, and forwards the navigation message back to the grid.
Below is a minimal code snippet to demonstrate this approach:
BOOL CMyPropertyGridCtrl::PreTranslateMessage(MSG* pMsg)
{
// Intercept Up / Down arrow keys
if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN))
{
CMFCPropertyGridProperty* pActiveProp = GetCurSel();
// Check if there is an active property and it is currently being edited
if (pActiveProp != nullptr && pActiveProp->IsInPlaceEditing())
{
// 1. Force the grid to end the edit mode.
// Pass TRUE to save the current text input, or FALSE to discard it.
this->EndEditItem(TRUE);
// 2. Forward the arrow key message to the property grid itself
// so it can handle the row up/down navigation natively.
::SendMessage(this->GetSafeHwnd(), WM_KEYDOWN, pMsg->wParam, pMsg->lParam);
// 3. Mark the message as handled so it doesn't reach the inner edit control.
return TRUE;
}
}
// Fall back to default message processing
return CMFCPropertyGridCtrl::PreTranslateMessage(pMsg);
}
For further reading, you can refer to the official Microsoft documentations on the methods and classes used in this workaround:
- CMFCPropertyGridCtrl Class Overview
- CMFCPropertyGridProperty::IsInPlaceEditing
- CMFCPropertyGridCtrl::EndEditItem
- CWnd::PreTranslateMessage
Hopefully, this provides you with enough information to decide which approach is best for your application's user experience. If you found my response helpful or informative, I would greatly appreciate it if you could follow this guide for your confirmation.
Thank you.