85 messaggi dal 26 gennaio 2007
Ciao a tutti, sono alle prese con una windows application.
Io ho una form principale midicontainer, divisa da uno splitContanier in due pannelli.All'interno di questa form ho un treeview con una funzione di popolamento pubblica. Nel metodo on load richiamo un'altra form in qeusto modo
NuovaForm nf = new NuovaForm();
nf.TopLevel = false;
nf.Parent = this.splitContainer1.Panel2;
In questa form ho un'azione di login,e vorrei che se il login va a buon fine si deve chiudere (riesco a farlo con il metodo Close()) e devo far creare il menu nella form principale richiamando la funzione pubblica.Ma non riesco?
come devo fare?
Grazie a tutti
501 messaggi dal 09 giugno 2006
Contributi
Ciao.

Ci sono diverse soluzioni. Ad esempio quando crei la seconda finestra (NuovaForm) di login, puoi pensare di passare un riferimento alla finestra principale in modo tale da poterne richiamare il metodo.

NELLA FORM PRINCIPALE
NuovaForm nf = new NuovaForm(); 
nf.TopLevel = false; 
nf.RiferimentoFormPrincipale = this; 
nf.Parent = this.splitContainer1.Panel2; 


NELLA FORM SECONDARIA
   this.RiferimentoFormPrincipale.AggiornaMenu();
   this.Close();


Chiaramente ho omesso il codice get/set della proprietà RiferimentoFormPrincipale ed ho assunto che il metodo AggiornaMenu sia nella forma principale e sia visibile.

Sebbene questa soluzione sia semplice è preferibile ricorrere all'uso di eventi/delegate.

Ciao.

.:. Marcello Rutter .:.
85 messaggi dal 26 gennaio 2007
scusa ma non ho capito l'elemento RiferimentoFormPrincipale di che tipo deve essere. E poi quale sarebbe l'altro motivo eventi/delegate??
Grazie mille per tutto
85 messaggi dal 26 gennaio 2007
Proprio nessuno riesce a rispondermi??
501 messaggi dal 09 giugno 2006
Contributi
Ciao.

Quando scrivi:
devo far creare il menu nella form principale richiamando la funzione pubblica


Cosa intendi esattamente? Dov'è scritta la funzione "pubblica"? Come si chiama il form principale che richiama il form NuovaForm?

Non ho approfondito la possibile soluzione basata su eventi/delegate perché non vorrei mettere troppa carne al fuoco. Prima di tutto cerchiamo di capirci sul primo punto e verificare che tutto sia ok, poi passeremo allo step 2.

Ciao.

.:. Marcello Rutter .:.
85 messaggi dal 26 gennaio 2007
Allora prima form
Form1.cs - all'interno è dichiarato un treeview - è definita una funzione public void carica_menu()

Seconda Form

Login.cs - azione di Login - se il login va a buon fine devo chiudere questa e richiamare il carica_menu() di Form1 e visualizzarlo

Grazie mille
501 messaggi dal 09 giugno 2006
Contributi
Ok, allora vediamo la soluzione con un po' di codice.

La prima consiste nel creare, in Login.cs, una proprietà pubblica (RiferimentoFormPrincipale) usata per passare a Login un riferimento di Form1. In questo modo Login potrà richiamare il metodo nella form principale.

La definizione della proprietà in Login.cs:
        // Definisco una variabile privata chiamata "_refForm1" di tipo "Form1"
        private Form1 _refForm1 = null;

        // Definisco una proprietà pubblica chiamata "RiferimentoFormPrincipale" di tipo "Form1"
        public Form1 RiferimentoFormPrincipale
        {
            get { return _refForm1; }
            set { _refForm1 = value; }
        }


Sempre in Login.cs, la chiamata al metodo del form principale da effettuarsi quando il login è ok:
            this.RiferimentoFormPrincipale.carica_menu();
            this.Close();


Infine in Form1 l'inizializzazione del form Login sarà qualcosa di simile a questo:

            Login nf = new Login();
            nf.TopLevel = false;
            nf.RiferimentoFormPrincipale = this;
            nf.Parent = this.splitContainer1.Panel2;


Questa tecnica prevede che venga passata una istanza di Form1 pertanto Form1 sarà interamente "visible" da parte di Login. Ora questo particolare non ti dirà molto ma in verità è la porta di accesso ai numerosi problemi legati alla sicurezza del codice tanto maggiori quanto il tuo lavoro andrà condiviso con altri sviluppatori.

Esiste quindi almeno un'altra soluzione che farebbe uso dei Delegate. Se non sai cosa sono ti suggerisco di approfondire l'argomento perché sono fondamentali. Per definizione un delegate è un tipo di dato che fa riferimento ad un metodo (cfr. MSDN). Una volta che assegni "il riferimento di un metodo" ad un delegate, il delegate si comporta come se tu utilizzasi direttamente il metodo. In molti parlano di delegate come di "puntatore a funzione" del linguaggio C e per certi versi è così anche se il delegate è molto di più.

Quindi la seconda possibile soluzione consiste in questo principio: io (Form1) chiamo te (Login) e ti passo un parametro per indicarti quale metodo devi richiamare se il login va bene. Il codice, più o meno, è il seguente:

Da qualche parte devi definire il delegate. Per comodità lo definiamo in Login:

        // Definisco un delegate
        public delegate void LoginEseguitoCallback();


Nella form Login definiamo una proprietà pubblica per memorizzare il valore del delegate:

        // Definisco una variabile privata di tipo "LoginEseguitoCallback"
        private LoginEseguitoCallback _hanlder = null;

        // Definisco una proprietà pubblica chiamata "LoginEseguitoHandler"
        // Sarà utilizzata per memorizzare il metodo associato al delegate
        public LoginEseguitoCallback LoginEseguitoHandler
        {
            get { return _hanlder; }
            set { _hanlder = value; }
        }


Ancora una volta sarà Login ad invocare il metodo in Form1 ma questa volta lo farà per mezzo del delegate e non accedendo al form direttamente. Ecco il codice da inserire nel metodo che gestisce il login:
            if (this.LoginEseguitoHandler != null)
                this.LoginEseguitoHandler();
            
            this.Close();


Infine, in Form1, provvederemo a creare una istanza di Login assegnando, al delegate, il metodo che desideriamo venga richiamato (spesso si utilizza il termine tecnico di Callback):

            Login nf = new Login();
            nf.TopLevel = false;
            nf.LoginEseguitoHandler = this.carica_menu;
            nf.Parent = this.splitContainer1.Panel2;


Finito. Il codice che ti ho postato è scritto così com'è, senza che l'abbia controllato (lascio a te scoprire eventuali errori).

Alla prossima.

.:. Marcello Rutter .:.
85 messaggi dal 26 gennaio 2007
grazie mille!!
certo il secondo metotdo è piu stile programmazione quindi sarebbe meglio usare quello!!
Sei stato molto molto chiaro
Grazie davvero

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.