Jump to content
Hugo Bendtner

Custom Control for TDBCtrlGrid showing only active data

Recommended Posts

I've recently been getting to grips with writing custom controls using TFieldDataLink and making them work with TDBCtrlGrid. I've pretty much copied the code from TDBText to get something similar (with differences).

 

I've learnt that I need

ControlStyle := ControlStyle + [csReplicatable];

so that I can drop the control onto a TDBCtrlGrid.

 

My problem is that the control shows the data of the active row in the dataset, bot for each row of the dataset.

So for instance if I bind to LineNumber field of my dataset of three records, it shows:

 

  • 1
  • 1
  • 1

 

And then clicking on the second row shows:

 

  • 2
  • 2
  • 2

 

Not:

 

  • 1
  • 2
  • 3

 

Snippets of my code:

constructor TMyDataLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  ControlStyle := ControlStyle + [csReplicatable];

  //Other code

  FDataLink := TFieldDataLink.Create;
  FDataLink.Control := Self;
  FDataLink.OnDataChange := DataChange;
end;

function TMyDataLabel.GetFieldText: string;
begin
  if FDataLink.Field <> nil then
    Result := FDataLink.Field.DisplayText
  else if csDesigning in ComponentState then
    Result := Name
  else
    Result := '';
end;

procedure TMyDataLabel.DataChange(Sender: TObject);
begin
  fLabel.Caption := GetFieldText;
end;

 

There is clearly something else I need to do to get it to work, but what is it? I'm thinking the DataLink isn't quite correct?

 

Share this post


Link to post

When a control has csReplicatable in its ControlStyle, it signals that it can be copied using the PaintTo method to draw its image to an arbitrary canvas. Perhaps that doesn't hold true for TMyDataLabel?

Share this post


Link to post

During the Paint method you have to handle csPaintCopy in ControlState (you can check in Vcl.DBCtrls).

  • Thanks 1

Share this post


Link to post

Yes, thank you for this.

 

I've overridden the Paint method, and fetch data from different sources depending on the ControlState.

 

procedure TMyDataLabel.Paint;
begin
  if (csPaintCopy in ControlState) and (FDataLink.Field <> nil) then
  begin
    fLabel.Caption:= FDataLink.Field.DisplayText;
  end
  else
    fLabel.Caption:= fBoundData;
end;

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×