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;