Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2003
    Messaggi
    17

    [DELPHI] Aggiungere campi in run-time

    Premettendo che sono ancora agli inizi col Delphi, vorrei porvi il seguente problema:
    Ho due form diversi che chiamerò A e B.
    In A inserisco un TEdit e un TButton, mentre B lo lascio vuoto.
    Vorrei che, premendo il TButton, si aprisse il form B con tanti TMemo quanto il numero specificato nel TEdit del form A.

    E' possibile? E come? (spero di essermi spiegato bene )

  2. #2
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Devi passare al secondo form (B) il numero contenuto nella casella del primo form (A), convertendolo eventualmente in un valore intero tramite la funzione StrToInt.

    Per creare controlli visuali a runtime, devi richiamare il metodo costruttore della classe corrispondente Create e assegnare la proprietà Parent, nonché definire i valori di Left e Top.

    Indicativamente

    codice:
    var
      MemoControl: TMemo;
    begin
      for i := 1 to NumberOfMemos do
      begin
        MemoControl := TMemo.Create(Self);
        MemoControl.Parent := Self;
        MemoControl.Left := 10;
        MemoControl.Top := 10;
        // ...
      end;
    end;
    L'esempio di codice prevede che le istruzioni vengano eseguite nel contesto della classe del form secondario, ad esempio nell'evento OnCreate, quindi l'identificatore Self rappresenta il riferimento (passato come parametro nascosto al metodo) all'istanza corrente della classe del form secondario.

    Non ho verificato la correttezza sintatica del codice, l'ho riportato solamente per fornire un esempio semplice, quindi va anche modificato opportunamente a seconda delle esigenze.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2003
    Messaggi
    17
    Adattato alle mie esigenze e funziona con numeri prestabiliti...tuttavia non riesco a passare la variabile dal form A al form B: mi rimane sempre 0

  4. #4
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Originariamente inviato da El Presy
    Adattato alle mie esigenze e funziona con numeri prestabiliti...tuttavia non riesco a passare la variabile dal form A al form B: mi rimane sempre 0
    Non posso vedere sul tuo PC, per fortuna, quindi se non scrivi il codice non posso nemmeno tentare ad indovinare quale può essere il motivo. :rollo:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  5. #5
    Utente di HTML.it
    Registrato dal
    Nov 2003
    Messaggi
    17
    Ops è vero

    Allora questo è il mio Form A con TEdit e TButton
    codice:
    unit A;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm_A = class(TForm)
        Edit1: TEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form_A: TForm_A;
    
    implementation
    
    uses B;
    
    {$R *.dfm}
    
    procedure TForm_A.Button1Click(Sender: TObject);
    begin
      Form_B.Numero := StrToInt(Edit1.Text);
      Form_B.ShowModal;
    end;
    
    end.
    Mentre questo è il Form B inizialmente vuoto
    codice:
    unit B;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm_B = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
        Numero: Integer;
      end;
    
    var
      Form_B: TForm_B;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm_B.FormCreate(Sender: TObject);
      var MemoControl: TMemo;
      var i: Integer;
      var x: Integer;
    begin
      x := 0;
      for i := 1 to Numero do
      begin
        MemoControl := TMemo.Create(Self);
        MemoControl.Parent := Self;
        MemoControl.Name := 'Memo_'+ IntToStr(i);
        MemoControl.Left := 10;
        MemoControl.Top := 10 + x;
        x := x + 50;
      end;
    end;
    
    end.

  6. #6
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Osservando il tuo codice, non vi è traccia delle istruzioni di creazione dei form, sia del primario che del secondario.

    Quindi, suppongo che la creazione avvenga in automatico, nel corpo principale del programma (come generalmente accade per impostazione predefinita in Delphi, cosa che non condivido).

    Il problema è dato dal fatto che l'inizializzazione del form secondario sfruttando il Numero memorizzato nell'apposito campo avviene all'interno dell'evento OnCreate; quando imposti il valore di quel campo, in verità, il form è già stato creato, quindi il codice di inizializzazione è già stato eseguito; il risultato che ottieni, quindi, è la semplice visualizzazione del form con i controlli visuali inizializzati precedentemente all'impostazione del numero di controlli, che non sortisce alcun effetto.

    Le soluzioni possibili sono due: spostare il codice di inizializzazione all'interno dell'evento OnShow o, manovra ideale, creare dinamicamente il form quando è necessario, inizializzandolo a dovere, usando il costruttore Create, analogamente a quanto si fa nel controllo.

    Puoi trovare le istruzioni necessarie per fare questo nel corpo principale del programma, in cui Delphi inserisce appunto tali comandi per creare i form all'avvio dell'applicazione.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2003
    Messaggi
    17
    Ah ora penso di aver capito:
    Di default i form in uses vengono creati all'avvio e distrutti alla chiusura di tutto il programma giusto? :master:
    Cerco di modificare un pò tutto e ti farò sapere.
    Grazie

  8. #8
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Originariamente inviato da El Presy
    Di default i form in uses vengono creati all'avvio e distrutti alla chiusura di tutto il programma giusto?
    La clausola uses, in questo caso, non c'entra nulla.

    Il programma principale (.DPR) ha la visibilità di tutte le unit e accede potenzialmente a tutti i tipi.

    Per impostazione predefinita, nel corpo principale del programma viene effettuata la creazione dei form. Modifica l'elenco dei form creati automaticamente dalla finestra delle opzioni del progetto.
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  9. #9
    Utente di HTML.it
    Registrato dal
    Nov 2003
    Messaggi
    17
    Finalmente funziona!
    Ho eliminato la variabile Numero e utilizzato direttamente il valore del TEdit (Magari c'è un modo migliore)

    Form A
    codice:
    unit A;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm_A = class(TForm)
        Edit1: TEdit;
        Button1: TButton;
        procedure Button1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form_A: TForm_A;
    
    implementation
    
    uses B;
    
    {$R *.dfm}
    
    procedure TForm_A.Button1Click(Sender: TObject);
    begin
      Application.CreateForm(TForm_B, Form_B);
      try
        Form_B.ShowModal;
      finally
        Form_B.Free;
      end;
    end;
    
    end.
    Form B
    codice:
    unit B;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
    
    type
      TForm_B = class(TForm)
        Button1: TButton;
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;
    
    var
      Form_B: TForm_B;
    
    implementation
    
    uses A;
    {$R *.dfm}
    
    procedure TForm_B.FormCreate(Sender: TObject);
      var MemoControl: TMemo;
      var i: Integer;
      var x: Integer;
    begin
      x := 0;
      for i := 1 to StrToInt(Form_A.Edit1.Text) do
      begin
        MemoControl := TMemo.Create(Self);
        MemoControl.Parent := Self;
        MemoControl.Name := 'Memo_'+ IntToStr(i);
        MemoControl.Left := 10;
        MemoControl.Top := 10 + x;
        x := x + 50;
      end;
    end;
    
    end.
    Grazie per l'aiuto

  10. #10
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,288
    Diciamo che, in generale, considerando la tua esigenza, il codice che hai scritto può essere accettato, benché in un'ottica OOP più ampia tenderei a considerarlo non corretto poiché fai riferimento, all'interno del codice di una classe, ad una variabile che contiene una precisa istanza del form che devi utilizzare (quello che fornisce il numero di controlli da creare).

    Se tu dovessi replicare questo meccanismo per un numero indefinito di form A e B, istanze delle rispettive classi, il tuo codice non funzionerebbe più (in quanto fai riferimento ad una variabile che punta all'ultimo oggetto creato).

    Dovresti semplicemente aggiungere un campo nel form B che contenga un riferimento al form A che lo "chiama" e copiare al suo interno tale riferimento prima della visualizzazione del form B, il quale preleverà il numero di controlli da creare attraverso tale riferimento.

    Ciao!
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.