Is it a question of settings or must you program this functionality ?
Yes, it is a question of settings and it doesn't require any code. However, there is evidently a problem in your project which I think you need to sort out first.
When you say "the grid jumps to some other random record in the grid,which is annoying.", it sounds as if you are starting from the the wrong place to try and get the navigation behaviour you want because jumping like that certainly shouldn't happen. And it doesn't in any cxGrid project of mine.
Anyway, I find that the representation of a cxGridDBTableView in the Object Inspector sometimes makes it hard to "see the wood for the trees". What I do then is to use a project which creates the grid entirely in code - see below.
The code below is completely self-contained and doesn't require any event handlers, persistent TFields, etc. If you try it, you should find that by default, as created, the grid does support up and down and left and right cell navigation using the cursor keys. The only exception is that the left and right keys don't work for cell navigation when the current cell contents are being edited. However, if you uncomment the line
cxView.DataController.Options := cxView.DataController.Options + [dcoImmediatePost];
then, pressing Enter
while editing in a cell immediately posts the edit back to the dataset, and the grid will allow you to navigate out of the cell by using the left- or right-arrow key. I'm sure there are fancier ways of achieving this effect by processing the key handling in code, but at least the dcoImmediatePost
method has the advantage of requiring no code.
When the app starts, you should see the see the top row "highlighted" (colored blue by default) except for its LH cell, which is focused.
Hopefully, this example will help you identify the cause of the "jumping" in your project and may also help you refine your description of what you would like to obtain, in terms of cursor-key navigation.
Code
procedure TForm1.CreateGrid;
begin
cxGrid := TcxGrid.Create(Self);
cxGrid.Parent := Self;
cxGrid.Width := 400;
cxLevel := cxGrid.Levels.Add;
cxLevel.Name := 'Firstlevel';
cxView := cxGrid.CreateView(TcxGridDBTableView) as TcxGridDBTableView;
cxView.Name := 'ATableView';
// Uncomment the following line to make the grid respond to the `Enter` key by posting any pending change to the data row
// cxView.DataController.Options := cxView.DataController.Options + [dcoImmediatePost];
cxView.DataController.KeyFieldNames := 'ID';
cxLevel.GridView := cxView;
cxView.DataController.DataSource := DS1;
cxView.DataController.CreateAllItems;
end;
function CreateField(AFieldClass : TFieldClass; AOwner : TComponent; ADataSet : TDataSet;
AFieldName, AName : String; ASize : Integer; AFieldKind : TFieldKind) : TField;
begin
Result := AFieldClass.Create(AOwner);
Result.FieldKind := AFieldKind;
Result.FieldName := AFieldName;
Result.Name := AName;
Result.Size := ASize;
Result.DataSet := ADataSet;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
Field : TField;
begin
Field := CreateField(TAutoIncField, Self, CDS1, 'ID', 'CDS1ID', 0, fkData);
Field := CreateField(TBooleanField, Self, CDS1, 'Marked', 'CDS1Marked', 0, fkData);
Field := CreateField(TStringField, Self, CDS1, 'Name', 'CDS1Namefield', 20, fkData);
Field := CreateField(TStringField, Self, CDS1, 'Value', 'CDS1Valuefield', 20, fkData);
CDS1.CreateDataSet;
CDS1.IndexFieldNames := 'ID';
for i := 1 to 5 do begin
CDS1.Insert;
CDS1.FieldByName('Marked').AsBoolean := Odd(i);
CDs1.FieldByName('Name').AsString := 'Name' + IntToStr(i);
CDs1.FieldByName('Value').AsString := 'Value ' + IntToStr(i);
CDS1.Post;
end;
CDS1.First;
CreateGrid;
ActiveControl := cxGrid;
end;