2012-09-04 101 views
0

我有一個TStringGrid有幾行,其中我實現了某種「只讀」行。更確切地說,我不允許用戶點擊倒數第二行。如果用戶單擊最後一行,則不會發生任何事情;焦點不會移動到該行的單元格中。如何防止滾輪選擇TStringGrid的最後一行?

我的代碼(在的KeyDown)一切都運行良好。 但是,如果用戶點擊最上面一行然後使用鼠標滾輪向下滾動,最終焦點將移動到倒數第二行。任何想法如何防止這一點?

+0

要回答你的問題,如何防止它......只要解決您的代碼,因爲您所描述的行爲與沒有任何事件處理的字符串網格的默認行爲不同。網格行選擇在滾動時會發生變化,但是每滾動一步而不是從第一行到倒數第二行(除非你有3行當然:-) – TLama

+0

@TLama - 我從來沒有說過它會從第一行跳到最後一行。如果用戶保持滾動,它將最終到達最後一行:) – Ampere

+0

那麼,我沒有得到零件,*如果用戶點擊最上面一行,然後使用鼠標滾輪向下滾動,焦點將移動到倒數第二排。任何想法* ***如何防止這種*** *?*這聽起來像它正在發生在你身上,你想要阻止這種行爲。 – TLama

回答

5

嗯,你可以重寫DoMouseWheelDown實現這一目標。

function TMyStringGrid.DoMouseWheelDown(Shift: TShiftState; 
    MousePos: TPoint): Boolean; 
begin 
    if Row<RowCount-2 then 
    //only allow wheel down if we are above the penultimate row 
    Result := inherited DoMouseWheelDown(Shift, MousePos) 
    else 
    Result := False; 
end; 

但是,您如何知道沒有其他方法將焦點移至最後一行?

其實是一個更好的解決方案是重寫SelectCell

function TMyStringGrid.SelectCell(ACol, ARow: Longint): Boolean; 
begin 
    Result := ARow<RowCount-1; 
end; 

當你做這樣你不需要任何KeyDown代碼,你不需要重寫DoMouseWheelDown。所有可能的機制將選定的單元格更改爲最後一行將被阻止。

由於@TLama正確地指出,你不需要TStringGrid子類來實現這一點。您可以使用OnSelectCell事件:

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Longint; 
    var CanSelect: Boolean); 
begin 
    CanSelect := ARow<(Sender as TStringGrid).RowCount-1; 
end; 
+0

似乎DoMouseWheelDown在事件(滾動)發生後被調用(當焦點離開只讀單元格/行時)。我在代碼中加入了一個BEEP,它證實了這一點。首先將焦點設置到我的只讀單元格,然後再滾動一次,然後聽到嘟嘟聲。 – Ampere

+1

不在我的TCustomGrid派生類中。無論如何,使用'SelectCell'。這一切都更好。一行代碼來完成一切。你可以把你所有的努力都挖出來。 –

+0

謝謝。好主意。 – Ampere

-1

我通過把這個事件OnMouseWheelUp解決了這個問題:

procedure Tmainform.sgup(Sender: TObject; Shift: TShiftState; 
    MousePos: TPoint; var Handled: Boolean); 
begin 
     sg.RowCount := sg.RowCount + 1; 
     sg.RowCount := sg.RowCount - 1; 
end; 
+0

抱歉,本網站採用英文版本,以便任何人都能理解答案。你能翻譯它嗎? – ZygD