Delphi 如何实现IsFirstRecord和IsLastRecord?
当用户单击控件毫无意义时,我喜欢禁用它们 一种特殊情况是一组自定义菜单按钮,模拟标准Delphi 如何实现IsFirstRecord和IsLastRecord?,delphi,delphi-xe2,tdataset,Delphi,Delphi Xe2,Tdataset,当用户单击控件毫无意义时,我喜欢禁用它们 一种特殊情况是一组自定义菜单按钮,模拟标准TDBNavigator的第一个、前一个、下一个和最后一个按钮 当用户单击第一个按钮时,第一个和前一个按钮都被禁用 然后,当用户单击“下一个”和“上一个”按钮时,基础的TDataSet与以前一样位于同一条记录上,但第一个和前一个按钮仍处于启用状态 当前的实现如下所示: NavigationFirstButton.Enabled := not DataSet.IsEmpty and not DataSet.Bof;
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;
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;
Bof
和Eof
不是禁用按钮的正确方法,因为我必须事先知道当前记录是否将是第一条/最后一条记录
所以我想用IsFirstRecord
和IsLastRecord
方法重写这个:
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
不正确的情况。(即过滤后的Tadskyry)
IsFirstRecord
和IsLastRecord
的可靠实现是什么?甚至可以使用当前的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;
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
PS.根据定义DataSet.Empty==DataSet.EOF和DataSet.BOF,因此检查是冗余的。我猜你指的是DataSet.Active而不是DataSet.Bof代码>记录计数在检查记录状态(比如备份/备份)时并不总是可用(想想动态数据集):禁用控件;保存书签;先前的;如果是BOF,则是第一条记录;恢复书签;启用控制;(您是对的,TDBNavigator做得不对)实际上没有必要检索记录数据来获得sql数据集的记录计数。事实上,我认为大多数数据集后代都会试图避免这种情况<例如,code>TSQLDataSet尝试运行
selectcount
查询Tadskyry
,同样,在服务器端做一些正常的事情并计算记录。@SertacAkyuz这意味着RecordCount
在ReadCommitted隔离级别下是不可靠的。你可能会得到100个,但事实上,很快你就会发现其中有105个或95个