我在使用TStringGrid和弹出菜单时遇到问题
我想知道从弹出菜单中选择项目时最后一个活动单元格的行/列。但是,当我单击弹出菜单时,StringGrid.Row返回为-1。
我尝试使用MouseToCell作为OnClick的一部分,但即使在设置了SG.Row之后它仍然在PopUp菜单例程中返回为-1 ...我怀疑问题是网格失去焦点。
是否有任何解决方案不需要OnClick设置全局变量?
我正在使用链接到弹出菜单上项目的动作列表,以确保工具栏和弹出菜单之间的操作一致
答案 0 :(得分:7)
我担心我不完全明白你的意思。当我左键单击字符串网格中的单元格时,它会被选中,但是当我右键单击它时则不会。当我右键单击它时,会显示弹出菜单(如果已分配),在MenuItemClick
上,我可以轻松阅读当前选中的row
和col
。请参阅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事件。下次按下鼠标按钮(任何按钮)时会调用它。
答案 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(类型声明);两种方式都很好,使代码更清晰。