2013-10-31 79 views
5

我喜歡禁用用戶點擊它們時毫無意義的控件。如何實現IsFirstRecord和IsLastRecord?

一個特例是一組自定義菜單按鈕,模擬標準TDBNavigator的第一個,之前,下一個和最後一個按鈕。

當用戶點擊第一個按鈕時,第一個和以前的按鈕都被禁用。

當用戶點擊下一個和上一個按鈕時,底層TDataSet與之前位於同一記錄上,但第一個和以前的按鈕都處於啓用狀態。

當前的實現看起來是這樣的:

NavigationFirstButton.Enabled := not DataSet.IsEmpty and not DataSet.Bof; 
NavigationPriorButton.Enabled := not DataSet.IsEmpty and not DataSet.Bof; 
NavigationNextButton.Enabled := not DataSet.IsEmpty and not DataSet.Eof; 
NavigationLastButton.Enabled := not DataSet.IsEmpty and not DataSet.Eof; 

BofEof不以禁用按鈕以正確的方式,因爲我事先知道,如果當前的記錄將是第一個/最後一個記錄。

所以我想重寫這個使用IsFirstRecordIsLastRecord方法:

function IsFirstRecord(ADataSet: TDataSet): Boolean; 
begin 
    Result := ADataSet.RecNo = 0; 
end; 

function IsLastRecord(ADataSet: TDataSet): Boolean; 
begin 
    Result := ADataSet.RecNo = ADataSet.RecordCount - 1; 
end; 

我不認爲這是一個好主意,因爲我見過的情況下,第一個記錄RecNo = 0不真正。 (即A過濾的TADSQuery)

什麼是IsFirstRecordIsLastRecord的可靠實現?它甚至有可能使用當前的TDataSet架構嗎?

+0

'RecNo'是可選的(可能是未執行)對於SQL數據集。 「RecordCount」對於SQL數據集不好,因爲它需要獲取所有數據。想象一下SQL SELECT請求,它會生成10GB的信息。通常,用戶只會分析第一個屏幕的數據(或者可能是3個屏幕或10個屏幕),然後關閉表單,忽略其他相關性較低的數據。通過調用.RecordCount,你要求1:SQL Server會按照正確的順序讀取光盤中的所有10GB數據2:網絡將傳輸所有這10GB數據3:客戶端將在RAM中緩存所有這10GB數據。 –

+0

因此,這將是服務器和網絡的壓力測試(減慢所有其他工作)以及客戶端內存不足。所有這些都是爲了可能永遠不需要的信息。所以'RecNo'方法對於ISAM數據庫(DBF,Paradox等)來說是正確的。對於SQL數據庫,正確的方法是使用「TDataSet.EOF」和「TDataSet.BOF」函數 –

+1

PS。根據定義DataSet.Empty == DataSet.EOF和DataSet.BOF,以便檢查是多餘的。我猜你的意思是'DataSet.Active而不是DataSet.Bof';' –

回答

5

你可以嘗試這樣的事:

function IsFirstRecord(ADataSet: TDataSet): Boolean; 
var 
    BmStr: TBookmarkStr; 
begin 
    Result := not ADataSet.IsEmpty; 
    if not Result then Exit; 
    Result := ADataSet.Bof; 
    // if ADataSet is already at BOF there is no point to continue 
    if not Result then 
    begin 
    ADataSet.DisableControls; 
    try 
     BmStr := ADataSet.Bookmark; 
     try 
     ADataSet.Prior; 
     Result := ADataSet.Bof; 
     finally 
     ADataSet.Bookmark := BmStr; 
     end; 
    finally 
     ADataSet.EnableControls; 
    end; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    if IsFirstRecord(ADODataSet1) then 
    ShowMessage('First') 
    else 
    ShowMessage('Not First'); 
end; 

對於IsLastRecord實現只需更換:

ADataSet.Prior -> ADataSet.Next 
ADataSet.Bof -> ADataSet.Eof