Reputation: 5377
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
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
:
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:
Upvotes: 4