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个