Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何在TDBGrid中设置活动单元?_Delphi_Dbgrid - Fatal编程技术网

Delphi 如何在TDBGrid中设置活动单元?

Delphi 如何在TDBGrid中设置活动单元?,delphi,dbgrid,Delphi,Dbgrid,我想按代码激活TDBGrid中的单元格。“激活”是指像用户在单元格内单击一样,准备编辑单元格内容。我怎么能这样做 编辑:这可能包括两个步骤:更改当前活动单元格,然后进入编辑模式。如果您的意思是“激活当前活动单元格的编辑模式”,那么您可能应该这样做: MyDBGrid.EditorMode := True; type THackDBGrid = class(TDBGrid); 激活特定单元格可以通过SelectedIndex: MyDBGrid.SelectedIndex := 2; {

我想按代码激活
TDBGrid
中的单元格。“激活”是指像用户在单元格内单击一样,准备编辑单元格内容。我怎么能这样做

编辑:这可能包括两个步骤:更改当前活动单元格,然后进入编辑模式。

如果您的意思是“激活当前活动单元格的编辑模式”,那么您可能应该这样做:

MyDBGrid.EditorMode := True;
type
  THackDBGrid = class(TDBGrid);
激活特定单元格可以通过
SelectedIndex

MyDBGrid.SelectedIndex := 2;  { or maybe MyDBGrid.SelectedIndex + 1 }
或通过
SelectedField

MyDBGrid.SelectedField := MyDataSet.FieldByName('Name');
要确定此时鼠标光标下的单元格,可以使用
MouseCoord
,它返回一条
TGridCoord
记录,记录光标下单元格的坐标。
TGridCoord.X
字段可直接用于设置网格的活动列

var
  Cell: TGridCoord;

...

Cell := MyDBGrid.MouseCoord(X, Y);
MyDBGrid.SelectedIndex := Cell.X;
设置行比较棘手,到目前为止,我能找到的唯一方法是所谓的受保护的hack,即访问类的受保护属性和方法的方法。我们需要“破解”的是
TDBGrid

基本上,您声明了
TDBGrid
的一个空子体,如下所示:

MyDBGrid.EditorMode := True;
type
  THackDBGrid = class(TDBGrid);
然后,当您需要访问受保护的属性或方法时,只需将标准类的实例(
MyDBGrid
在本例中)强制转换为“hacked”类型(
THackDBGrid
):

值不是绝对值:它相对于可见的顶行,但
TGridCoord.Y
也是绝对值,因此两者之间的差异对应于基础数据集中数据行之间的差异

我想强调一点:这种受保护的黑客方法应该谨慎使用。受保护的项目受到保护是有原因的。所以,如果你能避免,请这样做。如果您不能(没有其他方法或它可以帮助您更轻松地完成任务),请记住不要直接使用受保护的黑客更改任何内容。我的意思是,也许没关系,但一般来说你永远都不知道。您可以看到,我只使用该方法读取受保护的内容,没有直接更改任何内容。对象的状态最终被更改,但这是由
MoveBy
方法触发的标准机制的结果


您可以阅读有关受保护黑客的更多信息。

我的实现基于:

类型
TDBGridAccess=类(TDBGrid);
//将当前活动网格单元设置为(DestCol、DestRow)。这两个值都是
//相对于当前可见的左上栅格单元。
过程SelectDBGridCell(网格:TDBGrid;DestCol,DestRow:整数);
变量
CurrentRow:整数;
开始
如果未分配(Grid.DataSource)或未分配(Grid.DataSource.DataSet),则
出口
CurrentRow:=TDBGridAccess(网格).Row;
Grid.DataSource.DataSet.MoveBy(DestRow CurrentRow);
//检查最左边的网格列是否为没有
//数据集中的等效字段
如果dgIndicator在网格中。选项,则
Grid.SelectedIndex:=DestCol-1 else
Grid.SelectedIndex:=DestCol;
结束;
过程TDBGridController.HandleDBGridMouseMove(发送方:TObject;移位:TShiftState;X,Y:整数);
变量
细胞鼠:TGridCoord;
CurrentRow:整数;
DBGrid:TDBGrid;
开始
DBGrid:=作为TDBGrid的发送方;
CellAtMousePos:=DBGrid.MouseCoord(X,Y);
如果(CellAtMousePos.X-1)和(CellAtMousePos.Y-1),则
选择DBGridCell(DBGrid、CellAtMousePos.X、CellAtMousePos.Y);
结束;
(网格选择跟随鼠标光标。但是,
SelectDBGridCell
也可用于根据其他条件选择单元格。)


从技术角度看,它就像一种魅力。可用性是另一个问题。

我需要先更改当前活动的单元格-这就是我遇到的问题。(特别是我需要鼠标光标下的单元格。)我对问题进行了编辑,以更具体地说明这一点。@HeinrichUlbricht:更新了一种查找鼠标光标下单元格的方法。越来越近:)Y仍然被忽略。我需要能够自由指定选定的单元格-这包括行和列(或X和Y)。@HeinrichUlbricht:是的,看到了。挑起争端要复杂得多。好的,回到绘图板上。
type
  TDBGridAccess = class(TDBGrid);

// Set the currently active grid cell to (DestCol, DestRow). Both values are
// relative to the currently _visible_ upper left grid cell.
procedure SelectDBGridCell(Grid: TDBGrid; DestCol, DestRow: Integer);
var
  CurrentRow: Integer;
begin
  if not Assigned(Grid.DataSource) or not Assigned(Grid.DataSource.DataSet) then
    Exit;

  CurrentRow := TDBGridAccess(Grid).Row;
  Grid.DataSource.DataSet.MoveBy(DestRow-CurrentRow);
  // check if the leftmost grid column is the indicator column which has no
  // equivalent field in the dataset
  if dgIndicator in Grid.Options then
    Grid.SelectedIndex := DestCol-1 else
    Grid.SelectedIndex := DestCol;
end;

procedure TDBGridController.HandleDBGridMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  CellAtMousePos: TGridCoord;
  CurrentRow: Integer;
  DBGrid: TDBGrid;
begin
  DBGrid := Sender as TDBGrid;
  CellAtMousePos := DBGrid.MouseCoord(X, Y);
  if (CellAtMousePos.X<>-1) and (CellAtMousePos.Y<>-1)  then
    SelectDBGridCell(DBGrid, CellAtMousePos.X, CellAtMousePos.Y);
end;