如何实现IsFirstRecord和IsLastRecord?

Jen*_*off 5 delphi tdataset delphi-xe2

我喜欢在用户点击它们时没有意义的情况下禁用控件.

一个特殊情况是一组自定义菜单按钮,用于模拟标准的第一个,前一个,下一个和最后一个按钮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;
Run Code Online (Sandbox Code Playgroud)

Bof并且Eof不是禁用按钮的正确方法,因为我必须事先知道当前记录是否是第一个/最后一个记录.

所以我想用一个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;
Run Code Online (Sandbox Code Playgroud)

我不认为这是一个好主意,因为我已经看到第一个记录RecNo = 0不正确的情况.(即过滤的TADSQuery)

什么是可靠的实现IsFirstRecordIsLastRecord?甚至可以使用当前TDataSet架构吗?

kob*_*bik 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;
Run Code Online (Sandbox Code Playgroud)

对于IsLastRecord实现,只需替换:

ADataSet.Prior -> ADataSet.Next
ADataSet.Bof -> ADataSet.Eof
Run Code Online (Sandbox Code Playgroud)