delphiinsertaccess-violationstringgrid

Accessing StringGrid from another Form


Edit the body for more details.

I have a Form called ENP, defined in the EnpView unit. The ENP form, is created and shown from the handler event of a click a toolbar item in the Main Form (TPrincipal).

procedure TPrincipal.ENP1Click(Sender: TObject);
begin
  TENP.Create(self).Show();
end;

Enp form knows (in public declaration) clearGrid() message.

ENP Form have a TStringGrid called StringGrid. And a button called "Add". When click "Add" button other Form is created and shown: AddEnp form, defined in EnpViewAdd unit.

procedure TENP.opAgregarClick(Sender: TObject);
begin
  TAddEnp.Create(self).Show();
end;

The AddEnp form, have any TEdits. The values of the inputs must be adding in the EnpView.StringGrid.

I try this:

implementation

uses
  EnpView, Main;
procedure TAddEnp.AgregarClick(Sender: TObject);
begin

  { Agrego el nodo xml }
  Globals.Xml.agregarMuestra(muestra.Text);
  Globals.Xml.insertEnp(muestra.Text,golpes.Text,metros.Text);

  { Send messages to EnpView Form }
  ENP.clearGrid();
  ENP.populateGrid();

end;

ClearGrid messages fails in line 1, with access violation:

procedure TENP.clearGrid();
begin
  Self.StringGrid.RowCount := 2;
  Self.StringGrid.Rows[1].Clear();
end;

The clearGrid methods works if is send within the class. Any ideas ?.


Solution

  • Create a property named, for instance, ENPForm in TAddENP and assign the ENP form just after creating it. Declare it as follows:

    TAddENP = class(TForm)
    private
      FENPForm: TENP;
    
    // all of your already existing declarations
    
    public
      property ENPForm: TENP read FENPForm write FENPForm;
    end;
    

    Now that you have a possible reference to ENP form, you can use it as you like.

    During the creation of TAddENP form, do as follows:

    procedure TENP.opAgregarClick(Sender: TObject);
    var
      addForm: TAddENP;
    begin
      addForm := TAddEnp.Create(Self);
      addForm.EnpForm := Self;
      addForm.Show;
    end;
    

    Now you created the second form and gave it a secure reference to the first one. They can now talk to each other safely.

    I advise you to avoid having one form operating other one´s components, because this increses the dependency between them. Instead, declare public methods to do that, so the forms will depend on their interfaces, not their implementations.

    I hope this helps.