CHIAMATA FINESTRA

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”