对于任何实用程序,以相反顺序聚焦单元不支持RTL

时间:2016-08-29 04:53:43

标签: delphi

在DBGRID

中按相反顺序聚焦单元格

有些时候我得到一些DBGRID后代的组件,由于某种原因它不支持RTL,这引导我想到改变tab键的行为看起来是支持RTL,我唯一需要的就是改变标签键的方向。

我确信我的问题可以帮助任何需要RTL(如希伯来语和阿拉伯语)的用户使用一些不支持RTL的组件。

那引导我问:当按下按键以反转Tab键的操作时,如何更改按键动作,如下所示:

  • Tab键---> Shift Tab;

  • Shift Tab ---> Tab键;

1 个答案:

答案 0 :(得分:4)

以下代码没有 OnKeyUp处理程序,执行您想要的内容

    type
      TMyDBGrid = class(TDBGrid);

    procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift:
        TShiftState);
    begin
      if Key = VK_Tab then begin
        Key := 0;
        if ssShift in Shift then
          DBGrid1.SelectedIndex := DBGrid1.SelectedIndex + 1
        else begin
          if TMyDBGrid(DBGrid1).Col = 1 then begin
            //  The following goes to the rightmost cell in the next row 
            //  if the focus is already on the leftmost column, as specified
            //  in the original version of the q
            DBGrid1.DataSource.DataSet.Next;
            TMyDbGrid(DBGrid1).Col := DBGrid1.Columns.Count;
          end
          else
            DBGrid1.SelectedIndex := DBGrid1.SelectedIndex - 1;
        end;
      end;
    end;

更新在对此的评论中,您要求更全面的实施。这是:

procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word; Shift:
    TShiftState);

  procedure TabForwards;
  begin
    if TMyDBGrid(DBGrid1).Col = DBGrid1.Columns.Count then begin
      DBGrid1.DataSource.DataSet.Next;
      if DBGrid1.DataSource.DataSet.Eof then
        DBGrid1.DataSource.DataSet.Append;
      TMyDbGrid(DBGrid1).Col := 1;
    end
    else
      DBGrid1.SelectedIndex := DBGrid1.SelectedIndex + 1;
  end;

  procedure TabBackwards;
  begin
    if DBGrid1.DataSource.DataSet.State = dsInsert then begin
       DBGrid1.DataSource.DataSet.Cancel;
       Exit;
    end;

    if TMyDBGrid(DBGrid1).Row = 1 then begin
      if TMyDBGrid(DBGrid1).Col = 1 then
        TMyDBGrid(DBGrid1).Col := DBGrid1.Columns.Count
      else
        DBGrid1.SelectedIndex := DBGrid1.SelectedIndex - 1;
    end
    else begin
      if TMyDBGrid(DBGrid1).Col = 1 then begin
        DBGrid1.DataSource.DataSet.Prior;
        TMyDbGrid(DBGrid1).Col := DBGrid1.Columns.Count;
      end
      else
        DBGrid1.SelectedIndex := DBGrid1.SelectedIndex - 1;
    end;
  end;

begin
  Caption := IntToStr(TMyDbGrid(DBGrid1).RowCount);
  if cbNormal.Checked then
    Exit;
  if Key = VK_Tab then begin
    Key := 0;
    if ssShift in Shift then
      TabForwards
    else
      TabBackwards;
  end;
end;

请注意,这会使用TabForwardsTabBackwards子过程,并有效地反转Tab和Shift Tab的角色。这样做的原因是因为它将思考和谈论从关键组合中产生它的运动行为分开,我发现更容易编码和描述运动行为实际上是什么。

使用Tab和Shift选项卡作为标准,这就是DBGrid的行为方式:

  1. Tabbing forward“
  2. 如果光标在New Record行中,则焦点移动到行中的下一个单元格,直到它到达RH列,然后它将换行到第一列。

    否则,焦点移动到当前行中的下一个单元格,直到它到达RH列,然后它将换行到下一行的第一列(如果有的话),否则它会在网格的数据集上调用Append,然后移动到新记录行的第一列。

    在New Record行中,按Tab Backwards键放弃新记录。

    1. 向后跳转
    2. 如果光标位于“新建记录”行中,则会放弃新记录。否则,焦点移动到当前行中的前一个单元格,直到它到达LH列,然后它将换行到前一行的RH列。一旦它到达第一行的LH列,它就会包裹到该行的RH列。

      这就是第二个例子。

      但是,这不符合您在评论中所说的内容

        

      当我到达DBgrid中的最后一个单元格时,tab键(不是shift-Tab)需要打开新记录。

      这就是原因:

      您的方式,网格响应Tab键的行为在最后一个单元格中与其他单元格相比有所不同。在其他单元格中,Tab将向左移动并向上包裹到前一行,而在最后一个单元格中,它将向下移动。那会让我感到很困惑。无论如何,如果这真的是你想要的,你可以重新排列第二个例子以表现那样。

      以正常方式使用Tab和Shift Tab时,行为如下: