Pregunta

I like to disable controls when it's pointless for the user to click on them.

One special case is a set of custom menu buttons that emulate the first, prior, next and last buttons of a standard TDBNavigator.

When the user clicks on the first button, the first and prior buttons are both disabled.

When the user then clicks the next and prior buttons the underlying TDataSet is positioned on the same record as before, but the first and prior buttons are both still enabled.

The current implementation looks like this:

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;

Bof and Eof are not the right way to disable the buttons, because I have to know beforehand if the current record is going to be the first/last record.

So I thought of rewriting this using a IsFirstRecord and IsLastRecord method:

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

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

I don't think that this is a good idea, since I've seen cases where for the first record RecNo = 0 is not true. (i.e. A filtered TADSQuery)

What is a reliable implementation for IsFirstRecord and IsLastRecord? Is it even possible using the current TDataSet architecture?

¿Fue útil?

Solución

You could try something like this:

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;

For IsLastRecord implementation simply replace:

ADataSet.Prior -> ADataSet.Next
ADataSet.Bof -> ADataSet.Eof
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top