Al C
Al C

Reputation: 5377

What properties determine ClientDataSet field sizes?

I have an app that uses ClientDataSets and local file storage. Some of the info is displayed in a DB grid, and I found it was getting cut off--the first 500 characters or so of a string were displayed, but the underlying fields needed to be longer. So I went back to my code and increased the size of the underlying FieldDefs and also their display widths. I also created a new dataset (at design time). Finally, I ran the application, and created a new database. Nevertheless, only ~500 chars were displayed.

Where should I look to see what's limiting my field lengths?

Upvotes: 3

Views: 3851

Answers (1)

Ken White
Ken White

Reputation: 125620

I'd suspect you're running into an internal limitation of TDBGrid column widths, since a column that displays 500 characters would be more than a typical screen wide. (You can check this if you want to wade through the VCL source; start with Grids.pas.)

Typically, a TDBGrid doesn't display a lot of text in a single column. It leads to a lot of scrolling by the user, and horizontal scrolling to read wide text is extremely annoying to most people.

The usual way of doing this is to use an ftMemo type field, which can contain virtually unlimited text content. When the column is assigned to a TDBGrid, the grid column displays (MEMO), and the application handles a click or double-click on the column to display a secondary form with a TEdit or TRichEdit to display/edit the full contents of the column.

Here's an example of a TDBGrid attached to a TClientDataSet named CDS with the following columns defined (useless, but an example) using CDS.FieldDefs in the Object Inspector:

Column      Persistent Name    FieldType    Size
------      ---------------    ---------    ----
ID          CDSID              ftInteger     0
Name        CDSName            ftString     25
Notes       CDSNotes           ftMemo        0

Since the underlying dataset doesn't exist, I assign a FileName, and use the following code to create it at runtime:

procedure TForm1.FormCreate(Sender: TObject);
begin
  if not FileExists(CDS.FileName) then
  begin
    CDS.CreateDataSet;
    CDS.Active := True;
    CDS.InsertRecord([1, 'John Smith', 'This is some longer text'#13'for testing.']);
    CDS.InsertRecord([2, 'Fred Jones', 'A note about Fred goes'#13'here for now.']);
    CDS.Active := False;
  end;
  CDS.Active := True;
end;

I put a TDataSource on the form, and set it's DataSource to CDS. I added a TDBGrid, and set it's DataSet to DataSource1.

In the Object Inspector, choose the TDBGrid, go to the Events tab, and add the following to the OnCellClick event (just for display, of course):

procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
  if Column.FieldName := 'CDSNotes' then
    ShowMessage(Column.Field.AsString); // Display other form here instead
end;

Here's the display after clicking the CDSNotes column on row 1 of the TDBGrid:

enter image description here

If you must display partial content of a longer text column in the TDBGrid, you can use something like the following:

procedure TForm2.CDSNotesGetText(Sender: TField; var Text: string;
  DisplayText: Boolean);
begin
  // Again, a trivial example using an arbitrary chunk of the first 20
  // characters just for demo purposes.
  if DisplayText then
    Text := Copy(Sender.AsString, 1, 20)
  else
    // Not for display only; return all the text.
    Text := Sender.AsString;
end;

Doing so with the sample app above changes the display to this:

enter image description here

Upvotes: 4

Related Questions