每次更改TStringGrid的选定位置时会触发什么事件?

时间:2014-01-23 19:38:38

标签: delphi

我有一个stringgrid,显示了一堆文件和有关这些文件的信息。在单独的面板中显示有关当前所选项目的更多信息。所以,我想知道所选行何时更改以更新面板。 OnSelectCell并不好,因为它会在选择实际移动到新位置之前触发。这就是我的意思:

function TStrGrd.SelectCell(ACol, ARow: Longint): Boolean;   {override}
begin
 Result:= inherited SelectCell(ACol, ARow);
 Mesage('Cur row: '+ IntToStr(row));
 Mesage('New row: '+ IntToStr(ARow));

 { My own event }
 if Assigned(FCursorChanged)
 then FCursorChanged(Self);            <-------- user will see the old row
end;

如果选择了最后一行,我单击第一行,我将收到以下消息:

Cur row: 999
New row: 0

如果我创建自己的事件处理程序并将选择即将移动的行传递给它,它将起作用。它应该100%工作,但我对此不太满意,因为用户必须在该事件处理程序中编写一些额外的代码。

我可以拦截所有用户交互(鼠标/按键)以及我以编程方式进行的所有选择更改,但这需要相当多的代码。应该有一个更优雅的方式。

  1. 此问题与What event fires every time a TDbGrid's selected location is changed?类似,但不重复。该问题的答案是“使用OnDataChange”,但TStringGrid没有该事件。
  2. @Andriy M在此建议为什么OnSelectCell不起作用:Detecting single vs multiple selections in Delphi TStringGrid

1 个答案:

答案 0 :(得分:1)

不是答案。只需将其发布为多行文字。

我认为你的意思是“更新面板”而不是“关于”: - )

仍然无法解决ROW参数的问题。你说“用户必须在该事件处理程序中编写一些额外的代码。”但实际上恰恰相反。

procedure ParamEvent(const grid: TStringGrid; const Row: integer); 
begin
  ..do something with    grid.Rows[Row] to update the panel

//  ...and if I need, I also already know which Row was selected beforehand!
end;

procedure ParamLessEvent(); 
var grid: TStringGrid; Row: integer;    // <<<<< EXTRA "coding" here
begin
  grid :=  ..... some way to get the needed grid      // <<<<< EXTRA coding here
  Row  :=  grid.Row;        // <<<<< EXTRA coding here

  ...do something with    grid.Rows[Row] to update the panel

//  ...and if I would want to know which file just was DE-selected,
//   I would have to code persisting of previous selected row 
//   number somewhere outside the grid
end;

现在,真的,为什么不使用PostMessage?

const WM_Grid_Event = WM_USER + 123; // I hope it is correct? I always mix wm_user and wm_app
type TMyGrid = class (TStringGrid)
   ....
     private
       procedure DelayedEvent(var MSG: TMessage); message WM_Grid_Event;
     end;

function TMyGrid.SelectCell(ACol, ARow: Longint): Boolean;   {override}
begin
 Result:= inherited SelectCell(ACol, ARow);
 Mesage('Cur row: '+ IntToStr(row));
 Mesage('New row: '+ IntToStr(ARow));

 PostMessage( Self.Handle, WM_Grid_Event, ARow, 0);
end;

procedure DelayedEvent(var MSG: TMessage);
begin
  { My own event }
  if not Assigned(FCursorChanged) then exit;

  if Self.Row = MSG.WParam (* changed already? *) then begin
     FCursorChanged(Self);
  end else begin
     if MSG.LParam < 5 then // protection from infinite loop. OTOH I hope we would not EVER got here
        PostMessage( Self.Handle, WM_Grid_Event, MSG.WParam, 1 + MSG.LParam);
  end;
end;