Sono ancora a rompere le scatole per un problema …
Da una finestra con listbox chiamiamola ‘clientifornitori’ chiamo un’altra finestra ‘clientifornitori_’ in questo modo
dim w_clientifornitori as window
w_clientifornitori = clientifornitori_
w_clientifornitori.visualizza(xyz)
da w_clientifornitori aggiornarno la finestra ‘clientifornitori’ e fino qui sono apposto perch la finestra chiamante ha un nome ben preciso, mi basta controllare solo se aperta per richiamarla, o altrimenti se fosse chiusa si ri-aprirebbe;
Arriviamo al problema …
su clientifornitori_ ho una listbox che si chiama documenti che apro sempre come nuova istanza
dim w_documenti as window
w_documenti = documenti
w_documenti.visualizza(codiceclifor)
da w_documenti, nuova istanza di documenti come posso chiamare una funzione interna a w_clientifornitori alias di clientifornitori_ ???
Grazie e buona giornata a tutti.
Nella finestra chiamata w_documenti, creerei una propriet che si chiama per esempio FinestraChiamante con “type” = window
Quando apri w_documenti imposti la proriet w_documenti.FinestraChiamante = w_clientifornitori; a questo punto, da w_documenti puoi chiamare FinestraChiamante.NomeMetodo.
Prova, ma a occhio dovrebbe andare.
Ho fatto un esempio per testare l’idea. Funziona.
Progetto di esempio
Ho provato come mi hai indicato e funziona.
Ancora poche procedure ( beni ammortizzabili e F24 ) e il mio software di contabilit sar pronto.
Ottimo. Se ti serve un software di gestione documentale freeware dai un’occhiata la nostro DGED su www.divcon.ch
Si il metodo funziona ma attenzione che se chiudi la finestra 2 dell’esempio di Pietro dopo aver aperto la finestra 3 e poi premi il pulsante della 3 il programma va in crash.
Per evitare questo e anche possibili memory leak meglio (sempre basandosi sull’esempio di Pietro):
nel pulsante della window2 sostituire:
w.Chiamante=self
con
w.Chiamante = new WeakRef(Self)
nella window3:
definire chiamante come weakRef invece che window2
nel pulsante della window3 utilizzare:
if Chiamante<>nil and Chiamante.Value<>nil and Chiamante.Value isA Window2 then
Window2(Chiamante.Value).DataOra
end if
In questo modo non hai problemi.
Tra l’altro questo ti permette di non legare necessariamente ad una window l’azione. Magari puoi volerla realizzare in elementi diversi (parlo in generale), per questo magari puoi definire un’interfaccia:
ad esempio nel caso specifico dell’esempio puoi definire un’interfaccia visualizzatore_dataora con un metodo dataora
Definisci che window2 implementa questa interfaccia e nel pulsante della window3 scrivi:
if Chiamante<>nil and Chiamante.Value<>nil and Chiamante.Value isA visualizzatore_dataora then
visualizzatore_dataora(Chiamante.Value).DataOra
end if
In questo modo se vuoi usare un altro elemento che non sia window2 e/o che operi in risposta al comando in modo diverso, puoi farlo senza dover scrivere troppo codice.
Moooolto raffinato. Mi piace.
Bravo Antonio!
Pensavo appunto di adottare la soluzione di Antonio.
Huston abbiamo un problema :
Ho inserito in finestrabase ( che una classe finestra con alcune cose in comune tra tutte le finestre utilizzate nella mia APPS l’oggeto chiamante definito come weakRef
Quando chiamo qualsiasi finestra utilizzo quindi questo sistema :
dim prova as new modulofinestra
prova.chiamante = new weakref(self)
prova.funzione(“mia funzione”)
…
Per sviluppare poi una procedura di controllo per i permessi e quindi gestire l’accesso alle varie finestre
Su finestrabase implemento l’evento :
Function ConstructContextualMenu(base as MenuItem, x as Integer, y as Integer) As Boolean
if main.admin then
base.Append(New MenuItem("Sicurezza"))
end if
Return True //display the contextual menu
End Function
e l’evento :
Function ContextualMenuAction(hitItem as MenuItem) As Boolean
Dim c as New Clipboard
Select Case hititem.text
case "Sicurezza"
dim wf as new sicurezza
wf.chiamante = new WeakRef(self)
wf.Show
wf.target = replace(self.Title," ","-")
wf.visualizza("utente","procedura","testo")
End select
Return True
End Function
Premendo quindi il pulsante destro del mouse su tutte le finestre che utilizzano ‘finestrabase’ come super posso chiamare ‘sicurezza’ ( ovviamente sempre che una certa variabile sul modulobase sia impostata a true ‘main.admin = true’)
All’apertura di ‘sicurezza’ o comunque in questo caso una copia di ‘sicurezza’ ( dim wf as new sicurezza )
devo poter ottenere il nome della windows che ha chiamato l’oggetto;
Ho forse la possibilit in qualche modo di recuperare tale info dalla propriet chiamante della finestra ‘sicurezza’ ?
Ho provato in questo modo ma non funziona, anzi mi genera errore.
if main.admin = false then
self.close
else
Using Xojo.Introspection
Dim info As TypeInfo = GetType(chiamante)
MsgBox("Nome oggetto finestra name: " + info.FullName)
end if
Forse ti conviene utilizzare un’interfaccia ovvero la possibilit di definire che una classe (la tua chiamante) rispetti la presenza di alcuni metodi.
In questo modo invece che andare di introspezione, devi solo verificare che il tuo oggetto memorizzato nella weakref sia del tipo “interfaccia”. Se lo puoi chiamare dei metodi che magari accedono ad alcune propriet
Se poi deve essere di un tipo solo basta che verifichi che l’oggetto puntato sia di quel tipo.
Ho momentaneamente tamponato con una propriet che valorizzo quando chiamo la data finestra
esempio :
dim wf as new sicurezza
wf.chiamante = new weakref(self)
wf.targhet = “nome della finestra che ha chiamato”
