Delphi:StringGrid,位置和上下文菜单

时间:2010-08-19 14:49:50

标签: delphi delphi-2010 popupmenu tstringgrid

我在使用TStringGrid和弹出菜单时遇到问题

我想知道从弹出菜单中选择项目时最后一个活动单元格的行/列。但是,当我单击弹出菜单时,StringGrid.Row返回为-1。

我尝试使用MouseToCell作为OnClick的一部分,但即使在设置了SG.Row之后它仍然在PopUp菜单例程中返回为-1 ...我怀疑问题是网格失去焦点。

是否有任何解决方案不需要OnClick设置全局变量?

我正在使用链接到弹出菜单上项目的动作列表,以确保工具栏和弹出菜单之间的操作一致

4 个答案:

答案 0 :(得分:7)

我担心我不完全明白你的意思。当我左键单击字符串网格中的单元格时,它会被选中,但是当我右键单击它时则不会。当我右键单击它时,会显示弹出菜单(如果已分配),在MenuItemClick上,我可以轻松阅读当前选中的rowcol。请参阅example video

猜测您确实想要这样:您需要右键单击以更改活动单元格以及左键单击。这很容易做到:

procedure TForm1.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  if Button = mbRight then
    StringGrid1.Perform(WM_LBUTTONDOWN, 0, MakeLParam(Word(X), Word(Y)));
end;

答案 1 :(得分:0)

在我的一个基于TStringGrid的控件中,我使用MouseDown / MouseUp事件来处理该弹出菜单,因为我有两个不同的上下文菜单,具体取决于您单击的TStringGrid的哪个区域。奇迹般有效。只需确保在代码之前调用继承

-
请注意,弹出上下文菜单时,调用事件的顺序有些奇怪。更确切地说,当您按下RMB并弹出弹出菜单时,不会立即调用MouseUp事件。下次按下鼠标按钮(任何按钮)时会调用它。

另见:TStringGrid - OnMouseUp is not called!

答案 2 :(得分:0)

嗯......我无法在D2010中复制这个问题。

一个简单的想法是,问题可能是因为你没有选择任何行?是否会在Form的OnCreate帮助中首先将StringGrid的行预设为0?

答案 3 :(得分:0)

如果您需要/需要右键单击一个单元格将焦点移动到它(通常通过左键单击完成),您可以使用我用于此的代码:

type TStringGridHacked=class(Grids.TStringGrid); // This is to have access to hidden (and very usefull) methods, like MoveCol, MoveRow, FocusCell, etc
procedure TMyForm.TheStringGridMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
   ACol,ARow:Integer;
begin
     if mbRight=Button
     then begin // Right mouse button clicked
               TheStringGrid.MouseToCell(X,Y,ACol,ARow); // Convert X,Y coordinates of mouse to cell Col & Row
               if (FixedCols<=ACol)and(FixedRows<=ARow)
               then begin // Cell is not a header one
                         TStringGridHacked(TheStringGrid).FocusCell(ACol,ARow,True); // Send focus to such cell doing only one move, so triggering SelectCell only once
                    end;
          end;
end;

我一直在使用Hack type TStringGridHacked=class(Grids.TStringGrid)很长一段时间,因为我在互联网上找到它。

我在实现使用之后(如果我需要在同一单元上多次使用),或者在程序之前的代码中(如果我只需要它一次),就进行了这样的hack(类型声明);两种方式都很好,使代码更清晰。