2014-01-23 38 views
1

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

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
+0

你是什么意思“在选择实际移动之前”? “Row”和“Col”已经改变。 –

+2

我希望你可以PostMessage(POST不发送)到你的网格,某种你自己的WM_USER + delta。我希望在所有其他消息都能得到处理的时刻,你会得到你自己的定制消息 - 包括改变属性和绘画的所有工作都已经完成。事实上,PostMessage是WinGDI/VCL最常用的卸载任务的典型方式。 //然而,我的胆量感觉提示你只是想向你提供错误的工具。整个描述问题,您尝试通过延迟事件处理程序解决什么问题?也许你可以用更类似VCL的方式来解决它? –

+0

@ Arioch'The-请参阅更新的问题。 – Ampere

回答

1

不是答案。只是发布它有多行文本。

我想你的意思是“更新面板”,而不是“约” :-)

我仍然不能得到什么是错的行参数。你说“用户将不得不在该事件处理程序中编写一些额外的代码。”但实际上却恰恰相反。

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; 
+0

@你觉得还是你测试过的? –

+0

@Arioch - 不要担心,OP不会害羞,稍后将接受转换为他自己的答案。 –

+0

@ Arioch'The-我现在在我的电脑上,我可以测试它。看上去不错。无论如何,是最好的答案:) – Ampere

相关问题