I have tried a workaround and go through it and revert me if you have any concerns.
protected override bool ProcessKeyPreview(ref Message m) { int wParam = m.WParam.ToInt32();
switch (m.Msg)
{
case WM_KEYDOWN:
{
if (wParam == SHIFT)
{
isShiftDown = true;
return true;
}
}
break;
case WM_KEYUP:
{
if (wParam == TAB)
{
bool ismoved = moveSelectedGridItem(!isShiftDown);
// First: modify the method "moveSelectedGridItem" to return bool value (if grid moved: true, if TAB pressed after last grid item: false)
if(!ismoved)
// handle your implementaion here
return true;
}
else if (wParam == SHIFT)
{
isShiftDown = false;
return true;
}
}
break;
}
return ProcessKeyEventArgs(ref m);
}