Gambas-it

Gambas3 => Programmazione => Topic aperto da: perseo - 04 Novembre 2010, 16:56:24

Titolo: Form MDI
Inserito da: perseo - 04 Novembre 2010, 16:56:24
Dopo diverse sperimentazioni e tentativi sono giunto alla conclusione che il mio gestionale dovrebbe esse MDI-like.  :)

Questo è l'esempio che il mio mentore, milio, mi ha recentemente postato: un'immagine di un suo vecchio lavoro, che mi è piaciuta tantissimo. E' proprio come vorrei che fosse il mio layout.

http://milio.appix.net/Immagini/schermata3.png

La prima delle cose che non ho capito è la gestione degli eventi del WorkSpace (e quali sono gli eventi principali).

Per sperimentare ho popolato il mio WorkSpace con 3 form. Come faccio a richiamare un evento quando clicco su una linguetta del workspace di ognuno di questi?
Ad esempio, ipotizzando di avere delle gridbox in ogni form, mi serve che vengano aggiornate quando passo da un form ad un altro. Come si gestisce l'evento del cambio_form del workspace?
Titolo: Re: Form MDI
Inserito da: milio - 04 Novembre 2010, 18:39:56
Ogni Form rimane comunque indipendente, quindi la gestione del Form_Activate va realizzata sul Form e non nel WorkSpace...

Se poi vuoi che l'evento Form_Activate venga gestito dal Form che contiene il WorkSpace, allora bisogna utilizzare l'oggetto Observer...
Titolo: Re: Form MDI
Inserito da: perseo - 04 Novembre 2010, 21:18:49
Ottimo!
Mi serve di capire da chi e come vengono invocati, e la loro sequenza. Ho provato alcuni eventi, giusto per prendere dimestichezza... La guida on-line è abbastanza scarna di informazioni, anche se tutto sommato mi sembrano abbastanza intuitivi. Però ho alcune domande... che differenza c'è tra Activate e GotFocus?
Ho visto che Activate temporalmente precede GotFocus... ma non colgo la differenza.

[Edit]
Ho visto che nel tuo WorkSpace alcune linguette non si possono chiudere, sono "locked". Come si gestisce quella situazione, quando voglio impedire che alcune "linguette" siano chiuse?
Oppure ...come si inseriscono le icone nella linguetta, ecc.
Ho fatto vari tentativi ma non ne vengo a capo...  ???
[/Edit]


[Edit2]
Per le icone credo di aver capito...
Ho istanziato il form che voglio mettere nel WorkSpace, e ho caricato l'icona nel form_istanza... In questo modo l'icona del form_istanza viene caricata direttamente nel Tab del WorkSpace.  :)

Per il lockare il Tab ho pensato che  funzionasse allo stesso modo, cioè lockando il form_istanza... ma non so quale proprietà del form_istanza dovrei settare per verificare se così è corretto.  ???
[/Edit2]
Titolo: Re: Form MDI
Inserito da: milio - 05 Novembre 2010, 23:56:02
Non avevo voglia di risponderti a parole, anche perche' non mi spiego bene e ti creo solo confusione  ;D
Eccoti un bel esempio che vale mille parole...  ;)

Titolo: Re: Form MDI
Inserito da: perseo - 06 Novembre 2010, 03:03:44
Fantastico! Più di mille certamente!!!  :ok:
La logica è quella di impedire proprio la chiusura con lo STOP EVENT nel form_close()
E poi mi dai sempre degli spunti per capire altre cose. Ad esempio non sapevo che Property e relativi _read & _write potessero essere dichiarati anche in un form (pensavo si riferisse solo alle classi, ma tant'è visto che le form sono pur sempre classi...). Inizio a capire anche l'importanza di Object...  :)

Sinceramente, se non ci fossi tu sarei ancora ...a caro amico.  :2birre:
Titolo: Re: Form MDI
Inserito da: Golia - 06 Novembre 2010, 12:02:42
Adesso avete lanciato anche me!  :D
E' anche possibile fare una struttura ad albero nel listbox?
Titolo: Re: Form MDI
Inserito da: milio - 06 Novembre 2010, 12:04:45
@Perseo

Mi fa piacere che ti sia stato di aiuto...

Dovremmo fare, pero', una modifica al WorkSpace... possibilita' di caricare due form in uno stesso spazio di lavoro... work in progresssss......

@Golia
Basta che togli il ListBox dal pannello laterale e ci ficchi su un bel TreeView ;)
Titolo: Re: Form MDI
Inserito da: perseo - 06 Novembre 2010, 13:16:04
@ Milio,
Una WorkDouble?!  :ok:

Un chiarimento puramente tecnico... Nella Work ho sempre inserito i Form come istanze di form già creati... in modo tale da richiamare dal FMain (ossia quella con il Work) anche gli oggetti delle varie istanze, per fare ad esempio modifiche di label, oppure richiamare contenuti di caselle di testo, ecc.
Se invece inserisco i Form F1 da pulsante, usando ...Object.New(F1) tutte le istanze create... come le riconosco? Ho visto che si possono richiamare con "Workspace.Children[numero]..." però così non è immediatamente identificativo di ogni F1 istanziata.
La cosa che mi sembra più idonea è... visto che ogni F1 sarà la scheda personale di un utente, e che quindi visualizzerà il suo ID, ...potrei nella _new della F1 chiamare la Query al database e dopo scrivere F1.nome = hRes!IdUtente (questo è il suo campo)...
Così la F1 prenderebbe il nome IdUtente?

Intanto provo questo sistema e ti tengo aggiornato...  :)

@ Golia,
La TreeView, l'ho inserita appena scaricato il file... ed ho messo anche il menu.  ;)
Il mio codice prendilo con le molle. In alcuni punti l'ho modificato per fare sperimentare e capire meglio i comandi. Però mi pare ok!

Dalla riga15 dell'FMain trovi il caricamento degli item del TreeView, di nome "tv"
Me.tv.Add(1, "F1")
Me.tv.Add(2, "F2")
Me.tv.Add(3, "F3")
...

se vuoi inserire le icone nel TreeView basta che lo cambi così, aggiungendo la Picture... Ad esempio la riga17 potrebbe essere così:
Me.tv.Add(3, "F3", Picture.Load("encrypted.png"))
Titolo: Re: Form MDI
Inserito da: perseo - 06 Novembre 2010, 16:47:17
Che poi stavo pensando... in merito al WorkDouble...

Ma per la WorkSpaceDoppia basterebbe creare un Form_Padre che contenga due (o più) figli (disposti a sn/dx o up/down) separati magari da un sidepanel o un V/HSplit.
Il WorkSpace carica il padre... e poi nel _new del padre istanzio i figli che decido io...
Giusto?
Titolo: Re: Form MDI
Inserito da: milio - 06 Novembre 2010, 18:47:00
Esattissimo... solo che io voglio fare un drag and drop delle tab...
Titolo: Re: Form MDI
Inserito da: perseo - 06 Novembre 2010, 19:06:50
Come sempre riesci a stupirmi con effetti speciali... Cioè tu vorresti cliccare su un'icona che rappresenta un form ...e trascinarlo in una delle due metà del tab, nel work, a tuo piacimento?!  :o
Titolo: Re: Form MDI
Inserito da: milio - 06 Novembre 2010, 19:41:02
piu o meno... gambas ha la possibilita' di gestire il drag and drop.. quindi perche' non usarlo ;)
Titolo: Re: Form MDI
Inserito da: Golia - 06 Novembre 2010, 19:43:25
grazie degli esempi, stasera provo
Titolo: Re: Form MDI
Inserito da: andy60 - 07 Novembre 2010, 11:53:08
@milio

intendo fare il porting di un software crm scritto con access (non crocifiggetemi, mi serve in ufficio..), del quale allego la schermata principale. Dato che non esiste un crm di questo tipo x Linux penso possa essere interessante divulgarlo. E' possibile creare una mdi di questo tipo?
Titolo: Re: Form MDI
Inserito da: perseo - 07 Novembre 2010, 12:55:29
Grosse difficoltà...  :rolleyes:

Allora... ho aggiunto un secondo WorkSpace, in una delle finetre del WorkSpace (nella F3).
In pratica ho ridisegnato la F3, mettendo --> un ToolPanel. Al secondo pannello del ToolPanel ho inserito un Container con dentro due Buttons (btnAggiungi e btnElimina) ed il secondo Workspace (Workspace2).

La sequenza del percorso è --> Work1, F3, Toolpanel (secondo pannello), Work2 & i due Buttons.

Cliccando sul btnAggiungi --> nel Workspace mi viene aggiunto sempre lo stesso form, FX (un form con delle TextBox...).
Per fare questo... nel codice del form F3 ho inserito questo:
Codice: vb.net [Seleziona]
Public Sub ButtonX_Click()
  Dim i As Integer

  Me.Workspace2.Add(Object.New("FX"))
  For i = 1 To Me.Workspace2.Children.Count
    Me.Workspace2.Children[i - 1].Title = "FX n°" & i
    Me.Workspace2.Children[i - 1].Name = "FX" & i
  Next
End


Quindi ogni FX che aggiungo dovrebbe avere come Titolo (che compare nel TAB del Workspace2) e Name = "FX n°1" ed "FX1", "FX n°2" ed "FX2",  "FX n°3" ed "FX3", ecc.

Invece, cliccando sul btnElimina mi viene eliminata la TAB attiva. Chiaramente mi ricalcola anche i Titoli ed i Nomi, perché se elimino una delle TAB in mezzo, poi si creerebbe un salto di numerazione.
Codice: vb.net [Seleziona]
Public Sub Button2_Click()
  Dim i As Integer
  If Object.IsValid(Me.Workspace2.ActiveWindow) Then 'questo IF serve perché se cliccassi btnElimina con il Workspace vuoto mi restituirebbe giustamente errore...
    Me.Workspace2.ActiveWindow.Close
    For i = 1 To Me.Workspace2.Children.Count
      Me.Workspace2.Children[i - 1].title = "FX n°" & i
      Me.Workspace2.Children[i - 1].title = "FX" & i
    Next
  Endif
End


La domanda è... come faccio a far fare la stessa cosa dal parent? Ossia come faccio a rinumerare e rinominare tutte le TAB se l'eliminazione avviene dalla "x" del TAB anziché dal btnElimina?

PS:
Ho notato una cosa... quando inserisco istanze di FX tramite
Codice: [Seleziona]
Me.Workspace2.Add(Object.New("FX"))
in teoria inserisco dei NEW FX, ma sempre con lo stesso nome "FX"? Come fa Gambas a distinguerli? Perché non va in errore? Come faccio io a richiamarne uno anziché un altro?
Come faccio, sempre dal codice di F3, ad inserire del testo nelle txtbox, che si trovano nelle FX che ho creato dinamicamente?

Sto diventando matto appresso a queste cose... :mad: :-\

Però la struttura sta venendo una meraviglia, quindi voglio perseverare finché non arrivo alla soluzione!  :coder:
Titolo: Re: Form MDI
Inserito da: perseo - 07 Novembre 2010, 14:40:36
Allego un'immagine della GUI del progetto

(http://img593.imageshack.us/img593/3223/workspace.png)

http://img593.imageshack.us/img593/3223/workspace.png (http://img593.imageshack.us/img593/3223/workspace.png)
Titolo: Re: Form MDI
Inserito da: fsurfing - 07 Novembre 2010, 19:13:49
non ho guardato l' esempio di milio e magari mi dico una grossissima str.....a, però io prima di aggiungere un oggetto al workspace gli definerei antecedentemente i parametri principali

Codice: gambas [Seleziona]

    Public Sub ButtonX_Click()  
     Dim i As Integer  
     Dim tmpobj as fx

    tmpobj=new fx
    tmpobj.title="FX N°" & me.workspace2.count
    tmpobj.name="FX" & me.workspace2.count

    Me.Workspace2.Add(tmpobj)  
    

    End  


immagino che così le tab vengano chiamate in modo corretto e eliminandole rimangano corrette anche qulle rimanenti.

come scritto su , non ho mai usato workspace , il codice è scritto a memoria e magari è una cagata! :)
Titolo: Re: Form MDI
Inserito da: perseo - 07 Novembre 2010, 21:14:21
Grazie, fsurfing

adesso ogni form_figlio ha sia il corretto che il corretto nome.  :ok:
Non ho pensato che il .name ed il .title si possono dare direttamente all'istanza dell'oggetto form FX, prima che sia inglobata nel workspace.  :-[

Quello che non riesco ancora a capire è come si fa ad esempio a settare dal workspace il .text di una label che sta dentro questi form dinamici.

Inoltre chiudendo il TAB da icona "x" vorrei ri-attribuire ad ogni Tab del workspace il nuovo progressivo... ma anche qui buio totale.  ???
Titolo: Re: Form MDI
Inserito da: fsurfing - 08 Novembre 2010, 00:07:29
direi che dandogli un nome prima di applicarli dovresti poter chiamare la label1 presente in fx1 con un semplice fx1.label.text="pippo"

secondo me  no ha molto senso cambiare il nome di una scheda quando una viene eliminata, credo che per il novanta% dei casi se generi un nuovo documento e lo chiami pippo quel documento si chiamerà sempre pippo, non ha senso rinumerare le schede se non nel momento che salvi il documento .

teoricamente cmq il testo della tab è il title della form percui

fx1.text="nuovo nome"

oppure con loop tramite workspace.children

credo che comunque non sia molto utile fare troppe prove  se non hai già una idea ben precisa di cosa devi realizzare , anche perchè magari ti poni dei problemi che in realtà poi non dovrai affrontare
Titolo: Re: Form MDI
Inserito da: perseo - 08 Novembre 2010, 01:04:09
Grazie mille fsurfing,  :)
Ho provato a mettere un: FX1.label.text = "..." ...ma mi restituisce errore.

In linea di massima vorrei che la struttura del mio gestionale fosse proprio così (sempre che io abbia la capacità di gestirla).
Sul nominativo delle TAB in effetti sarebbe molto più semplice evitare di usare numeri progressivi, ma se fosse possibile li preferirei. Il gestionale riguarderà un laboratorio di analisi cliniche, ed il form in questione dovrebbe rappresentare l'accettazione del paziente. Nel ToolPanel, dove ho messo il secondo workspace, vorrei inserire in progressione le ricette del paziente (se non usassi un progressivo, per distinguerla l'una dall'altra dovrei usare il codice_ricetta... che è un codice a 16 cifre... ma t'immagini ogni Tab con 16 caratteri alfanumerici... :D ).
In questo modo, completato F3, ossia il pannello di accettazione_paziente (negli altri ToolPanel metterei nominativi, note varie, e nell'altro ancora il ricapitolo di tutte le prestazioni richieste, ecc.), premendo un tasto andrei a popolare tutto il DB, dei dati relativi all'accettazione del paziente.
Ed è per questo che mi serve anche capire come recuperare questi dati, inseriti nelle textbox di ogni form_ricetta dinamico, concatenate nel workspace di F3.
[Avevo ipotizzato di usare una TABSTRIP, probabilmente molto più semplice da gestire rispetto al Workspace, però poi ho trovato un post sul forum in cui si parlava di mal funzionamento delle TabStrips quando inglobano dei forms... ed allora ho preferito optare per il Workspace (che mi sembra anche più performante...)].

E' un progetto ambizioso, ma spero di riuscire a farcela. Mi darebbe molta soddisfazione. Sono assalito da tanti dubbi proprio perché non voglio commettere errori o distrazioni, dando per scontate cose che poi potrei pagare in seguito. Quindi spesso vi riempio di domande anche su cose apparentemente insensate (ed a volte mi date la conferma che lo sono...).  :)

PS: spero capirai le tante domande poste fin qui: l'interfacciamento con lo scanner per inserire i referti in allegato... il calcolo del Codice Fiscale fondamentale per l'accettazione dei pazienti... ed ho già dato uno sguardo a PDF_Write per la stampa delle liste di lavoro e dei referti. In linea di massima mi sembra di vedere un po' di orizzonte, appena appena... ;)
Titolo: Re: Form MDI
Inserito da: milio - 08 Novembre 2010, 15:03:51
Scusate se non mi sono fatto sentire questo week ma telecom a deciso di farmi inc.....e  :evil:

Premesso che l'esempio su cui abbiamo lavorato fin'ora e' da prendere con le molle :)... e' stato tutto strutturato 'alla muzzo' ed e' solamente per scopi grafici...
Quello che ha detto fsurfing e' giustissimo, pero' devi anche capire che nel codice non puoi far riferimento ad un oggetto che ancora non esiste ;)
Infatti nel nostro esempio le Form vengono create di volta in volta solo per 'riempire' velocemente un workspace.

Nel tuo caso dovrai crearti un FormPaziente che si 'setterà' in base hai parametri che gli passi al momento della sua creazione e poi passarlo la WorkSpace in questo modo:

Public Sub AggiungiFormPaziente(IdPaziente as Integer)
Dim FCli As FCliente

  FCli = New FCliente(IdPaziente)
  WorkSpace.Add(FCli)

End

Facendo in questo modo, e avendo impostato la Form che si 'setti' in base all'idPaziente (esempio si imposta una query che in base all'id preleva il nominativo del paziente in modo da abbinarlo al Titolo del Form), se devi cambiare dall'esterno del Form, un valore di un oggetto in esso contenuto, l'unico modo per farlo è richiamare il Form con WorkSpace.Children[nr]....

Come al solito non mi saro' spiegato molto bene :( , allora ti lasci questo esempiuccio... fammi sapere ;)
Titolo: Re: Form MDI
Inserito da: milio - 08 Novembre 2010, 15:59:55
Citazione
[Avevo ipotizzato di usare una TABSTRIP, probabilmente molto più semplice da gestire rispetto al Workspace, però poi ho trovato un post sul forum in cui si parlava di mal funzionamento delle TabStrips quando inglobano dei forms... ed allora ho preferito optare per il Workspace (che mi sembra anche più performante...)].

Dovresti darti un'occhiata al sorgente del WorkSpace ;)
Titolo: Re: Form MDI
Inserito da: milio - 08 Novembre 2010, 16:36:15
@milio

intendo fare il porting di un software crm scritto con access (non crocifiggetemi, mi serve in ufficio..), del quale allego la schermata principale. Dato che non esiste un crm di questo tipo x Linux penso possa essere interessante divulgarlo. E' possibile creare una mdi di questo tipo?

A prima vista mi sembrano tutte form indipendenti con una toolbox per il menu'... non mi sembra che ci siano form mdi...
Titolo: Re: Form MDI
Inserito da: perseo - 08 Novembre 2010, 23:07:31
Milio come sempre sei gentilissimo!

Provo a postarti nei commenti ciò che ho capito del tuo codice, riguardo la FMain:
Codice: vb.net [Seleziona]

' Gambas class file

Public DbC As New Connection
Private Paziente As FPazienti 'questo l'ho modificato io... L'ho reso Private perché dopo ne richiamo la textbox1, all'evento "Button1_Click()" (un bottone che ho aggiunto io per fare una prova...)

Public Sub _new() 'qui è semplice... :)
  With DbC
    .Type = "sqlite3"
    .Host = Application.Path
    .Name = "pazienti"
  End With
  With Me.TreeView1
    .Add("GPaz", "Gestione Pazienti", Picture["access.png"])
    .Add("FPazienti", "Scheda Pazienti", Picture["class.png"], "GPaz")
    .Add("NPazienti", "Nuovo Paziente", Picture["new.png"], "GPaz")
  End With
End

Public Sub InsPaziente(IdPaziente As Integer) 'qui istanzia un nuovo form FPazienti relativo all'IdPaziente X... che viene ottenuto dall'attivazione della TreeView, e viene aggiunto al WorkSpace
  Paziente = New FPazienti(IdPaziente) As "paz"
  Me.Workspace1.Add(Paziente)
End

Public Function CercaPaziente(IdPaziente As Integer) As Integer 'qui si fa la ricerca tra i children (le TAB) della WorkSpace, in cui i nomi (che finiscono con un numero) combaciano con IdP...
'Se li trova --> Return Nx ...altrimenti Return -1. Questa operazione serve anche a vedere se l'IdP scelto è già stato aperto (istanziato)...
Dim Nx As Integer
  If IdPaziente = -1 Then Return -1
  For Nx = 0 To Me.Workspace1.Children.Max
    If Me.Workspace1.Children[Nx].Name = "Paziente_" & IdPaziente Then Return Nx
  Next
  Return -1
End

Public Sub TreeView1_Activate()
Dim Id, IdP As Integer
  If TreeView1.Current.Key = "FPazienti" Then 'qui chiede se ho attivato la TV sul pulsante "FPazienti" --> ossia scheda già esistente
    IdP = FP.Run() 'se sì --> chiama la funzione pubblica di FP, che si chiama "run" -->
    'Questa funzione "run" apre il DB e carica i nomi che ci sono in una combobox (in FP, in showmodal).
    'Quando clicchi su "ok" restituisce il valore "id" del paziente... che a sua volta viene restituito a IdP.
    'Altrimenti restituisce IdP = -1 (vale a dire che ho cliccato sul tasto "annulla" della FP oppure il TAB del paziente è già aperto)
    If IdP = -1 Then Return  'Se IdP = -1 --> non fare niente ...return
    Id = CercaPaziente(IdP)  'Id --> chiama la funzione pubblica CercaPaziente(IdP), con l'IdP da cercare, che era stato scelto dalla combobox di prima...
    If Id = -1 Then 'se non c'è nessun paziente...
      InsPaziente(IdP) '...allora inseriscilo del Database--> tramite InsPaziente(IdP)
    Else 'altrimenti...
      Me.Workspace1.ActiveWindow = Me.Workspace1.Children[Id]  'attiva la TAB dell'Id già aperto
    Endif
  Else If TreeView1.Current.Key = "NPazienti" Then  'qui chiede se ho attivato la TV sul pulsante "NPazienti" --> ossia nuova scheda
    IdP = FNP.Run() 'se sì --> chiama la funzione pubblica di FNP, che si chiama "run" che restituisce sempre IdP. Altrimenti restituisce IdP = -1 (vale a dire che ho cliccato sul tasto "annulla" della FNP)
    If IdP = -1 Then Return  'Se IdP = -1 --> non fare niente ...return
    InsPaziente(IdP) '...allora inseriscilo nel Database--> tramite la funzione InsPaziente(IdP)
  Endif
End

Public Sub Button1_Click()
  Paziente.TextBox1.Text = "Pierino!!!"  'richiama l'oggetto TextBox1 che sta nel form FP e gli cambia una textbox... Quindi da WorkSpace riesco finalmente a cambiare una proprietà di un suo children!
End


Spero di non aver scritto grosse stupidaggini tra i commenti...

Il fatto è che ho capito meglio, ma ancora non mi è chiara una cosa. Nella mia sperimentazione, quando clicco sul bottone (Button1) riesco a cambiare la textbox dell'ultima istanza aggiunta nel WorkSpace. Questo perché l'ultima istanza è "Persona" che è stata dichiarata Private, e che quindi è attiva.
Se invece volessi cambiare la textbox1 di un'altra istanza (una di quelle aperte precedentemente), come la richiamo? Cioè come si richiama un'istanza conoscendone il nome?


PS: il paziente numero 3 è grave!  :D
Titolo: Re: Form MDI
Inserito da: milio - 09 Novembre 2010, 09:59:21
Tutto giusto tranne questa:

Codice: vb [Seleziona]
  Id = CercaPaziente(IdP)  'Id --> chiama la funzione pubblica CercaPaziente(IdP), con l'IdP da cercare, che era stato scelto dalla combobox di prima...  
  If Id = -1 Then 'se non c'è nessun paziente... 
    InsPaziente(IdP) '...allora inseriscilo del Database--> tramite InsPaziente(IdP) 
  Else 'altrimenti... 
    Me.Workspace1.ActiveWindow = Me.Workspace1.Children[Id]  'attiva la TAB dell'Id già aperto 
  Endif


InsPaziente(IdP) e' una Sub che inserisce una nuova FormPaziente nel WorkSpace...

Citazione
Il fatto è che ho capito meglio, ma ancora non mi è chiara una cosa. Nella mia sperimentazione, quando clicco sul bottone (Button1) riesco a cambiare la textbox dell'ultima istanza aggiunta nel WorkSpace. Questo perché l'ultima istanza è "Persona" che è stata dichiarata Private, e che quindi è attiva.
Se invece volessi cambiare la textbox1 di un'altra istanza (una di quelle aperte precedentemente), come la richiamo? Cioè come si richiama un'istanza conoscendone il nome?

Come gia' scritto in qualche post sopra, devi sfruttare la Proprietà WorkSpace.Children[] per richiamare il form che vuoi modificare:
nell'esempio, ad esempio :) , puoi sfruttare l'id Paziente per richiamare il suo form facendo in questo modo:


Codice: vb [Seleziona]
Public Sub btnCambioSessoSilvio_Click()
Dim FPaz As FPazienti

  FPaz = Me.WorkSpace1.Children[CercaPaziente(3)]
  FPaz.TextBox4.Text = "F"

End


Con questa riga di codice (naturalmente la scheda di questo paziente deve essere aperta) ho appena cambiato il sesso del Sig. Silvio BungaBunga ;)
Titolo: Re: Form MDI
Inserito da: perseo - 09 Novembre 2010, 11:12:05
Hai perfettamente ragione una è una Sub l'altra una Function...

Ora ho capito! Io avevo provato a fare una cosa simile ma non so perché mi restituiva sempre errore...

Quindi...

Per richiamare l'FPazienti (che deve essere aperto ...ma qui basterebbe fare un controllo) uso la Sub cercapaziente(IdP). Questa restituisce il numero progressivo di TAB aperta nel WorkSpace... una volta attribuita l'istanza FPazienti ad FPaz... posso interaggire con tutti gli oggetti di FPaz!
In pratica questa riga di codice è l'anello di collegamento tra il Work e le sue TAB...
 FPaz = Me.WorkSpace1.Children[X]

Stavo pensando che quindi le TAB vengono richiamate per numerica progressiva. Sta a me fare combaciare questo numero al nome del paziente (tu usi un metodo "testuale" --> in pratica aggiungi quel numero progressivo in fondo al nome della tab e poi glielo fai sottrarre in fase di ricerca.
Indi, se volessi modificare il campo "sesso" della TAB attualmente attiva il codice sarebbe simile a questo...
Codice: vb.net [Seleziona]

Public Sub Button1_Click()
Dim FPaz As FPazienti  
Dim Nx As Integer
  For Nx = 0 To Me.Workspace1.Children.Max
    If Me.Workspace1.Children[Nx].Name = Me.Workspace1.ActiveWindow.Name Then FPaz = Me.WorkSpace1.Children[nx]
  Next
   If Me.Workspace1.ActiveWindow.Name = Me.Workspace1.Children[CercaPaziente(3)].Name Then Message.Info("Mi consenta!")
   FPaz.TextBox4.Text = "F"
End


Sempre assodato che almeno una TAB sia aperta...  ;)

Ho aggiunto nella FPaziente un tetbox5 dove va inserita l'altezza del paziente... Se quindi voglio estrarre i campi "Altezza" di ogni TAB...
Codice: vb.net [Seleziona]

Public Sub Button1_Click()
Dim FPaz As FPazienti 
Dim Nx As Integer
Dim iAltezza As String
  For Nx = 0 To Me.Workspace1.Children.Max
    FPaz = Me.WorkSpace1.Children[nx]
    If trim(FPaz.TextBox5.Text) <> Null Then
      iAltezza &= FPaz.TextBox5.Text & " "
    Else
      Me.Workspace1.ActiveWindow = Me.Workspace1.Children[Nx]
      Message.Warning("Non hai specificato l'altezza di " & Me.Workspace1.Children[Nx].Title & "!")
      Return
    Endif
  Next
    iAltezza = Trim(iAltezza)
    Message.Info("Le altezze inserite sono: " & iAltezza)
End


Il codice è molto sbrigativo... ma giusto per capire se avevo capito.

Ora credo di aver capito!  :2birre: :2birre:
Titolo: Re: Form MDI
Inserito da: milio - 09 Novembre 2010, 11:43:27
Bene...

Ti mandero' il conto  ;D

Citazione
Indi, se volessi modificare il campo "sesso" della TAB attualmente attiva il codice sarebbe simile a questo...
Per la TAB attualmente attiva, ti basta fare:

Public Sub Button1_Click()  
Dim FPaz As FPazienti

  FPaz = Me.WorkSpace1.ActiveWindow
  FPaz.TextBox4.Text = "F"

End

Comunque si potrebbe anche riprendere in mano il codice del WorkSpace e farci gia' al suo interno delle funzioni di ricerca in cui ti restituisca direttamente, tramite nome oggetto, la form desiderata... mi spiego meglio:

al posto di dichiarare una variabile che mi identifichi la Form come fatto nell'esempio, facendo opportune modifiche basterebbe fare:

Codice: vb [Seleziona]
  ME.WorkSpace[NomeForm].TextBox4.Text = "F"


Che dici, potrebbe essere utile?
Titolo: Re: Form MDI
Inserito da: perseo - 09 Novembre 2010, 12:07:51
Sarebbe sicuramente utile, ma poi sarebbe troppo facile usarlo... Devono soffrire come ho sofferto io! :evil:
Quindi direi di no!  :rotfl:

Scherzi a parte... credo che sarebbe utilissimo!  :ok:

Ho visto molti progetti in giro e pochissimi che utilizzano i WorkSpace... Domotiga lo usa... però ne fa un uso marginale (in pratica sono decine di form che vengono richiamate nei TAB senza neppure essere istanziate, e comunque il codice viene gestito prevalentemente dal codice del TAB).
Quello che mi hai spiegato tu sul WorkSpace non l'ho trovato scritto da nessuna parte nel web. Credo che bisognerebbe fare una guida, magari anche tradotta in inglese. Il componente merita e secondo me viene usato poco perché di difficile comprensione (almeno per chi è alle prime armi come me).
E se tu agevolassi l'uso del WorkSpace con questa modifica credo che spingeresti anche il WorkSpace ad essere usato di più.

Sei un grande! :)
Titolo: Re: Form MDI
Inserito da: milio - 09 Novembre 2010, 12:15:39
Citazione
Quello che mi hai spiegato tu sul WorkSpace non l'ho trovato scritto da nessuna parte nel web. Credo che bisognerebbe fare una guida
Piano Piano... diciamo che ho imparato bene le basi di gambas, e quindi basta sbirciare il sorgente del componente per rendersi conto di cosa gli si puo' far fare e cosa gli si puo' aggiungere...
Citazione
magari anche tradotta in inglese
L'inglese? parola a me sconosciuta  :P
Citazione
E se tu agevolassi l'uso del WorkSpace con questa modifica credo che spingeresti anche il WorkSpace ad essere usato di più.
ho scoperto una cosa interessante:

Codice: vb [Seleziona]
  Object.SetProperty(Me.WorkSpace1.Children[0]["TextBox4"], "Text", "F")


In un botto solo ti setto la proprietà Text del TextBox4 del TAB 0 senza dichiarare alcuna variabile ;)
Titolo: Re: Form MDI
Inserito da: perseo - 09 Novembre 2010, 13:26:30
Bingo!  :2birre: :2birre:

Sono giorni che ero alla ricerca di un metodo per richiamare direttamente la proprietà "text" dell'oggetto "TextboxX" del "TabX"... Questa è meravigliosa perché non bisogna neppure più istanziare la FPaz... ma basta solo identificare l'Id della Tab...

E quindi, volendo invece ottenere il valore di una proprietà di un oggetto (la proprietà "text" dei campi "nome", ad esempio, della TAB Attiva)...

Codice: vb.net [Seleziona]

Object.GetProperty(Me.WorkSpace1.ActiveWindow["TextBox1"], "Text")


 :ok:

PS: ho in vaga memoria il fatto che in VB6 usare il codice con SetProperty e/o GetProperty influisse anche sulla velocità di esecuzione dell'azione rispetto alle classiche textbox1.text = "..." oppure nome=textbox1.text. Tu sai qualcosa al riguardo o mi ricordo male io?!

PPS: dove posso scaricare i sorgenti di questi componenti? Oppure sono già nel mio computer in qualche cartella di Gambas3?
[Sorgenti componenti risolto... http://www.gambas-it.org/smf/index.php?topic=438.0 (http://www.gambas-it.org/smf/index.php?topic=438.0)]
Titolo: Re: Form MDI
Inserito da: milio - 09 Novembre 2010, 13:41:32
Bhe sicuramente e' meno performante che attribuire la proprietà direttamente, ma qui stiamo parlando di inserire del testo in un TextBox, e comunque tutto quello che concerne un gestionale non ha grosse pretese...
Magari una cosa da fare e' dare una sbirciatina al codice dell'oggetto Object per verificare che 'giro fa' per impostare una proprietà con quel metodo. Magari si riesce a replicare la cosa con una funzione piu' 'performante'
Titolo: Re: Form MDI
Inserito da: perseo - 09 Novembre 2010, 15:48:02
Ho notato una cosa...

Mentre nel normale codice una textbox non è "case sensitive", quindi possiamo tranquillamente chiamarla Textbox1.text = "..." oppure textbox1.text = "...", da Set/GetProprerty il nome è "case sensitive". Attenzione quindi, perché se non rispettiamo il nome esatto il compilatore restituirà Error (Object Null).

@ milio:
Ho provato a richiamare il testo inserito in una searchbox... Perfetto!  ;)
Titolo: Re: Form MDI
Inserito da: milio - 09 Novembre 2010, 15:58:07
Ma ti riferisci a una SearchBox inserita in un Form nel WorkSpace, oppure alle ultime modifiche che ho fatto al componente?
Titolo: Re: Form MDI
Inserito da: perseo - 09 Novembre 2010, 16:32:57
Mi riferivo ad una SearchBox nel Form del WorkSpace...

PS: la versione 0.0.17 di SearchBox l'ho scaricata ma ancora la devo testare, anche perché non so neppure bene come si usano quelle nuove proprietà che hai inserite...  ;D
Titolo: Re: Form MDI
Inserito da: perseo - 16 Novembre 2010, 23:13:38
Mai cantare vittoria! :hatecomputer:  ;D

Questa non credo di poterci arrivare...
Da un Form esterno ho richiamato il .Text di una TextBox1 che si trova nella Tab(0) della WorkSpace1 dell'FMain:

Codice: vb.net [Seleziona]
stringa = Object.GetProperty(FMain.Workspace1.Children[0]["TextBox1"], "Text")


Se la TextBox1 è nel Tab(0) --> tutt'ok e mi restituisce il valore...
...ma se la TextBox1 è dentro un toolpanel del Tab(0) il programma va in errore ("Object Null")

Chiaramente la mia TextBox sta dentro un toolpanel.
Per scrupolo ho provato a togliere la TextBox1 da dentro al toolpanel e a metterla in un panel qualsiasi del Tab(0)... e viene letta correttamente.

Non capisco proprio come fare...  :rolleyes:

Ho messo un allegato esplicativo... così chi vuol provare capisce meglio la situazione. L'esempio che ho allegato funziona. Ma se andate nel sorgente "Form2" e levate l'apice di commento alla riga10 vedrete che il programma va in errore... L'unica differenza tra le due textbox è che la seconda sta dentro un toolpanel.
Titolo: Re: Form MDI
Inserito da: md9327 - 17 Novembre 2010, 10:48:56
Analizzare dinamicamente gli oggetti grafici presenti in una form, compresa la loro struttura gerarchica, può essere alquanto complicato, ma dipende da cosa vuoi veramente ottenere.

Ad esempio, se vuoi rilevare tutti gli oggetti TextBox presenti in una Form, indipendentemente se sono collegati direttamente alla Form, oppure che siano inseriti in altri controlli, devi farti dei loop sulla proprietà Children che è disponibile in ogni controllo contenitore (ovvero derivato da Container).
Verificando poi ogni elemento di Children, che sia corrispondente ad una TextBox, rilevare le sue proprietà è immediato. Se poi incontri un Container, basta rifare il loop anche qui su Children, e così via...
Titolo: Re: Form MDI
Inserito da: milio - 17 Novembre 2010, 11:24:41
I casi sono due:
o hai creato il Form prima di inserirlo nel WorkSpace, come nel tuo caso delle schede pazienti, e quindi conosci la classe genitore FPazienti contenente l'oggetto da aggiornare, allora puoi tornare a fare come avevamo gia' scritto qualche post fa:

Codice: vb [Seleziona]
Public Sub Button3_Click()
Dim F As FPazienti

  If Object.Is(Me.Workspace1.ActiveWindow, "FPazienti") Then
    F = Me.Workspace1.ActiveWindow
    F.TextBox5.Text = "Ciao!"
  Endif

End


Se invece al WorkSpace gli passi un Form direttamente, allora ti basta richiamare l'oggetto normalmente come faresti per un qualsiasi altro Form aperto...

allego solito esempio...
Titolo: Re: Form MDI
Inserito da: perseo - 17 Novembre 2010, 11:29:52
MD... ti ringrazio molto della spiegazione, ma anche facendo il loop non riesco a spiegarmi il perché di alcuni comportamenti, tipo questo che segue...

La cosa incredibile che ho scoperto ora è questa:
Se l'oggetto textbox2 viene inserito in una TabStrip il programma non va in errore! E va bè... ma la cosa che mi rimane assurda è questa:
Per sperimentare un po' ho messo dei container vari, e cliccandoci sopra la Textbox migra dentro di essi...
Se la TextBox parte dentro ad una TabStrip e poi viene spostata in un controllo dove darebbe errore (tipo il Toolpanel) --> allora non da più errore!

Cioè, se la TextBox sta dentro alcuni tipi di container da errore ...ma se dentro quei container ci viene messa a seguito di qualche evento non da più errore... e riesco a leggere il suo contenuto (.Text) tranquillamente! :o

Perché?

[edit]
Grazie, milio... ho scaricato il tuo esempio. Me lo studio immediatamente...
[/edit]
Titolo: Re: Form MDI
Inserito da: perseo - 17 Novembre 2010, 12:17:43
Milio,

inutile dirti che il tutto funziona perfettamente, e non sai quanto sia felice! Dopo giorni d'impegno a fare la Form d'inserimento pazienti ero molto sfiduciato quando non riuscivo a venire a capo di questa cosa...
In pratica, come al solito, sbagliavo l'approccio (ed ora anche le parole di MD mi sono più chiare).
Se ho capito bene, la prassi migliore è clonare la Form del WorkSpace che m'interessa in un'immagine virtuale della Form dinamica (Dim F As "NomeForm" - e poi F = Me.Workspace.ActiveWindow). Ho provato anche a sostituire ActiveWindow con Children[X] e funziona perfettamente!  ;).
Adesso, da questa F (clone della Form dentro la Workspace) posso richiedere o settare le cose che m'interessano.

Il procedimento credo ora di averlo capito, ma quello che non mi entra ancora nella testa è perché non si possa fare direttamente. Piano piano credo che lo capirò.

PS: giusto per curiosità ...ma perchè dentro il ToolPanel (o altri tipi di container) mi dava errore e dentro una TabStrip no?
Titolo: Re: Form MDI
Inserito da: md9327 - 17 Novembre 2010, 16:24:03
Credo che tu faccia ancora confusione con la gestione degli oggetti, cosa abbastanza normale per chi è ancora nuovo con questo tipo di cose...

Quando dichiari una variabile "F", di tipo "Form", e usi il costrutto NEW, in realtà tu crei un'istanza di quell'oggetto ovvero , usando il nome dell'oggetto Form come template, tu vai a creare fisicamente una sua immagine in memoria, ossia una cosa che ha una struttura di quel tipo (variabili, funzioni e metodi).

Comunque, a parte questo piccolo chiarimento, che spero ti sia utile, mi pare alquanto strano il comportamento che hai segnalato.

La parte grafica è normalmente composta, o componibile, da tue tipi di oggetti base (desumibile anche dalla documentazione): Container e Control.
Il primo può assumere un'aspetto visibile o meno, ma in ogni caso ha la funzione principale di fungere appunto da contenitore di altri oggetti grafici (anche altri Container), e si presuppone siano in grado di gestire le modalità con cui presentare a video gli oggetti che esso contiene.
Del secondo tipo  fanno parte tutti quegli oggetti che hanno una funzione interattiva, ovvero visibili su schermo, e che potrebbero avere funzionalità attive (es. TextBox), oppure no (es. Label).
Questi ultimi hanno la necessità di essere inseriti in un contesto preciso, appunto un contenitore (Container), per funzionare. Di base può essere una Form, che è in pratica il contenitore di base, ma possono essere inseriti in altri tipi di contenitore, e così via...

Adesso non posso dire con precisione e sicurezza se in effetti la cosa si comporta in maniera differente, in base al tipo di contenitore, ma se questo è vero è sicuramente un errore di gambas, oppure fai tu qualcosa di sbagliato, che magari ti sfugge...

Io posso solo dirti che a me non è mai successo, e di combinazioni ne ho fatte parecchie. Questo mi fà più pensare a qualche tua manovra errata, oppure ad una versione o libreria gambas fallata.
Titolo: Re: Form MDI
Inserito da: perseo - 17 Novembre 2010, 16:42:11
MD,
hai ragione... Ancora faccio confusione, ma spero pian piano di riuscire a prendere dimestichezza con Gambas (e la OOP) in generale.

Comunque a testimonianza di questa mia breve esperienza ho allegato (nel post precedente) un esempio in cui il compilatore va in errore se la TextBox2 è nel toolpanel, mentre non va in errore se è in una tabstrip.
Se hai due secondi puoi scaricarlo e provarlo al volo, così mi dai conferma che l'errore è mio e non del compilatore, ed io mi metto l'anima in pace.  :)

PS. Per mandarlo in errore basta che da "visuale" tagli ed incolli la "TextBox2" dalla "TabStrip" al "ToolPanel". e poi esegui... Noterai che nella finestrella di controllo (Form2), riporta l'Error (nel label in rosso).
Titolo: Re: Form MDI
Inserito da: md9327 - 18 Novembre 2010, 11:14:03
Appena posso vedo... ti farò sapere...