Recent

Author Topic: [SOLVED] Detect changes in a StringGrid  (Read 12955 times)

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
[SOLVED] Detect changes in a StringGrid
« on: August 27, 2013, 01:39:15 pm »
Hi

I must be able to detect any change in a cell of a stringGrid (with goEditing=true), before the OnEditingDone event is called, before exiting the cell or the grid.

For keyboard input, I can use OnKeyUp, no problem.

But I someone use the context menu, how can I be sure to detect a change ? The OnClick or OnMouseUp/Down events are not fired by a right-click.

The only way I see for now, is to make a custom popup menu to overload the default one.

Is there any other simpler way ?

Thanks for any idea.
« Last Edit: August 28, 2013, 01:58:51 pm by tintinux »
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Detect changes in a StringGrid
« Reply #1 on: August 27, 2013, 02:37:37 pm »
One possible solution may be to use an Editmask. You can constrain the characters as they are entered, but they are not acted on util the cell is exited.

Set it like this:

Code: [Select]
Procedure TForm1.StringGrid1GetEditMask(Sender: TObject; ACol, ARow: integer;
  Var Value: string);
Begin
  //'!' = delete leading blanks. '0' = position must be a number.
  //'1' = keep formatting symbols. '_' =  trailing '0'.
  //Does not limit fields to 23:59:59.
  //Use ValidateEntry and Copy()to check and change each character as the cell is exited.
  If (ARow > 0) and (ACol = 1) Then
    Value := '!99:99:99;1;_';
End;

Validate it like this:

Code: [Select]
Procedure TForm1.StringGrid1ValidateEntry(Sender: TObject; aCol, aRow: integer;
  Const OldValue: string; Var NewValue: string);
Var
  I: integer;
Begin
  //Constrain to '23:59:59'.
  //This only takes effect on leaving cell.
  If (aRow > 0) and (aCol = 1) Then
  Begin
    If Copy(NewValue, 1, 1) > '2' Then
      NewValue[1] := '2';
    If Copy(NewValue, 2, 1) > '3' Then
      NewValue[2] := '3';
    If Copy(NewValue, 4, 1) > '5' Then
      NewValue[4] := '5';
    If Copy(NewValue, 7, 1) > '5' Then
      NewValue[7] := '5';

    For I := 1 To length(NewValue) Do //Replace any empty characters with '0' ie #32
      If (Copy(NewValue, I, 1) = ' ') Then
        NewValue[I] := '0';

    If (length(NewValue) = 0) Then   //Insert '00:00:00' if no value is entered.
      NewValue := '00:00:00';
  End;
End;


Bart

  • Hero Member
  • *****
  • Posts: 5571
    • Bart en Mariska's Webstek
Re: Detect changes in a StringGrid
« Reply #2 on: August 27, 2013, 02:42:23 pm »
When the Editor becomes active hook into it's OnChange event ?

Bart

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
Re: Detect changes in a StringGrid
« Reply #3 on: August 27, 2013, 02:46:44 pm »
When the Editor becomes active hook into it's OnChange event ?
Unfortunately, there is no OnChange  event in the StringGrid.
Can you explain a little more ?
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
Re: Detect changes in a StringGrid
« Reply #4 on: August 27, 2013, 02:50:08 pm »
One possible solution may be to use an Editmask. You can constrain the characters as they are entered, but they are not acted on util the cell is exited....
I don't not understand how your reply is linked to my question...
I don't need any constraint here, and I can't wait the OnValidate event to detect the changes.
Regards
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

Bart

  • Hero Member
  • *****
  • Posts: 5571
    • Bart en Mariska's Webstek
Re: Detect changes in a StringGrid
« Reply #5 on: August 27, 2013, 05:22:58 pm »
When the Editor becomes active hook into it's OnChange event ?
Unfortunately, there is no OnChange  event in the StringGrid.
Can you explain a little more ?
Totally untested code !!

Code: [Select]
procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
  var Editor: TWinControl);
begin
  if (Editor is TStringCellEditor) then
  begin
    TStringCellEditor(Editor).OnChange := @foo;
  end;
end;

Bart

Windsurfer

  • Sr. Member
  • ****
  • Posts: 368
    • Windsurfer
Re: Detect changes in a StringGrid
« Reply #6 on: August 27, 2013, 09:06:27 pm »
AFAIK the onValidate event fires for each keystroke (It does for the example I provided) so it does not wait until the cell is exited. It can check for anything you can code a test for.

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
Re: Detect changes in a StringGrid
« Reply #7 on: August 28, 2013, 08:55:26 am »
AFAIK the onValidate event fires for each keystroke (It does for the example I provided) so it does not wait until the cell is exited. It can check for anything you can code a test for.
No, you are wrong, the Onvalidate event is fired only when the cell is exited, and it is a right like this.
Regards
« Last Edit: August 28, 2013, 01:59:22 pm by tintinux »
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
Re: Detect changes in a StringGrid
« Reply #8 on: August 28, 2013, 09:22:40 am »
When the Editor becomes active hook into it's OnChange event ?
Unfortunately, there is no OnChange  event in the StringGrid.
Can you explain a little more ?
Totally untested code !!

Code: [Select]
procedure TForm1.StringGrid1SelectEditor(Sender: TObject; aCol, aRow: Integer;
  var Editor: TWinControl);
begin
  if (Editor is TStringCellEditor) then
  begin
    TStringCellEditor(Editor).OnChange := @foo;
  end;
end;

Bart

Thanks for the hint. It compiles and  works but the OnChange is called also when we enter in a non empty cell, using an arrow key. Maybe the SelectAll occuring at this time triggers the OnChange (I don't know why).

I'm looking for a workaround, comparing the entered value with the initial value when the cell is selected.

What about an OnChange event directly in the TCustomStringGrid in a next version ?

Regards
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

Bart

  • Hero Member
  • *****
  • Posts: 5571
    • Bart en Mariska's Webstek
Re: Detect changes in a StringGrid
« Reply #9 on: August 28, 2013, 10:56:24 am »
What about an OnChange event directly in the TCustomStringGrid in a next version ?

Please file a feauture request in the bugtracker.

Bart

Bart

  • Hero Member
  • *****
  • Posts: 5571
    • Bart en Mariska's Webstek
Re: Detect changes in a StringGrid
« Reply #10 on: August 28, 2013, 11:09:14 am »
Thanks for the hint. It compiles and  works but the OnChange is called also when we enter in a non empty cell, using an arrow key. Maybe the SelectAll occuring at this time triggers the OnChange (I don't know why).
No, it is because the content of the cell gets assigned to the editors text property then.
It then fires the OnSetEditText event b.t.w. (which makes my previous reply "hook OnChange" a bit silly).

Bart

tintinux

  • Sr. Member
  • ****
  • Posts: 365
    • Gestinux
Re: Detect changes in a StringGrid
« Reply #11 on: August 28, 2013, 01:58:37 pm »
So, the solution is very simple, no need for a hook.
Thanks for your help.
I'll post the feature request and until include this in my TStringGrid descendant.
Regards

Code: [Select]
procedure TForm1.StringGrid1Selection(Sender: TObject; aCol, aRow: Integer);
begin
  InitialValue := StringGrid1.Cells[aCol,aRow];
  label1.Caption := 'Initial Value = '''+InitialValue+'''';
end;

procedure TForm1.StringGrid1SetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: string);
begin
  if Value <> InitialValue then
    label1.Caption := 'New Value = '''+Value+'''';
end;
Initiator of gestinux, open-source, multi-database and multilingual accounting and billing software made with LAZARUS.

You can help to develop, to make and improve translations, and to provide examples of legal charts and reports from more countries.

 

TinyPortal © 2005-2018