[Lazarus] Increasingly frustrated with DbGrids
Luca Olivetti
luca at wetron.es
Wed Jun 22 12:18:04 CEST 2016
El 02/11/15 a les 11:56, Luca Olivetti ha escrit:
> El 02/11/15 a les 11:12, Luca Olivetti ha escrit:
>> Hello,
>>
>> I constantly stumble with the behaviour of the TDBGrid.
>> I understand that it's a complex component, but every time I find an
>> issue an Luiz fixes it, two more pop up (or an older one resurfaces).
>> The latest episode of the saga is the futility of using a custom editor
>> (with OnSelectEditor), since the grids then sets the value of the field
>> using this snippet of code
>>
>> if (FEditor<>nil) and FEditor.Visible then begin
>> Msg.LclMsg.msg:=GM_GETVALUE;
>> Msg.grid:=Self;
>> Msg.Col:=FCol;
>> Msg.Row:=FRow;
>> Msg.Value:=GetCells(FCol, FRow);
>> FEditor.Dispatch(Msg);
>> SetEditText(Msg.Col, Msg.Row, Msg.Value);
>> end;
>>
>> and this only works with the editors defined in Grids.pas, the only ones
>> managing the GM_GETVALUE message.
>> For other kinds of editors the result depends on how you move in the
>> grid: it could either maintain the value the editor set or reset it to
>> an empty string.
>>
>> I think I will file a bug once I can create a simple project, but in the
>> meantime if somebody has an idea on how to solve it, it would be
>> appreciated.
>
>
> Bug created:
>
> http://bugs.freepascal.org/view.php?id=28944
As I said in the bug report I just discovered
http://www.freepascal.org/~michael/articles/grids/grids.pdf (published
in 2008!) describing how to correctly implement a custom editor (so the
method from the wiki I originally used is wrong, I also added a note to
the wiki).
*However* the component described by Michaƫl only works with a
StringGrid, not with a DBGrid: when you change cell the grids sends the
GM_SETVALUE message *before* the GM_GETVALUE one, so the edited value is
lost and a semi-random one is used instead.
To make it work one has to override the Change method (as it is done in
grids.pas):
procedure TStringCellEditor.Change;
begin
{$IfDef DbgGrid} DebugLn('TStringCellEditor.Change INIT
text=',Text);{$ENDIF}
inherited Change;
if (FGrid<>nil) and Visible then begin
FGrid.EditorTextChanged(FCol, FRow, Text);
end;
{$IfDef DbgGrid} DebugLn('TStringCellEditor.Change END');{$ENDIF}
end;
*but* the EditorTextChanged method is protected, so an additional
cracker class (ugly) has to be used, e.g.
TMyGrid = class(TCustomGrid)
procedure EditorTextChanged(const aCol, aRow: Integer; const aText:
string); override;
end;
procedure TMyGrid.EditorTextChanged(const aCol, aRow: Integer;
const aText: string);
begin
inherited EditorTextChanged(aCol, aRow, aText);
end;
procedure TMyEditor.Change;
begin
if (FGrid<>nil) and Visible then begin
TMyGrid(FGrid).EditorTextChanged(FCol, FRow, Text);
end;
Maybe EditorTextChanged (and others methods to be used in custom
editors) should be public?
Comments?
Is there something else that I'm missing?
Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010) Fax +34 93 5883007
More information about the Lazarus
mailing list