Autore Topic: Form MDI  (Letto 6755 volte)

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #15 il: 07 Novembre 2010, 14:40:36 »
Allego un'immagine della GUI del progetto



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

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: Form MDI
« Risposta #16 il: 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! :)

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #17 il: 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.  ???

Offline fsurfing

  • Moderatore
  • Senatore Gambero
  • *****
  • Post: 2.482
    • Mostra profilo
Re: Form MDI
« Risposta #18 il: 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

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #19 il: 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... ;)

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #20 il: 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 ;)

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #21 il: 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 ;)

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #22 il: 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...

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #23 il: 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
« Ultima modifica: 08 Novembre 2010, 23:17:36 da perseo »

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #24 il: 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 ;)

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #25 il: 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:
« Ultima modifica: 09 Novembre 2010, 11:51:11 da perseo »

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #26 il: 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?

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #27 il: 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! :)

Offline milio

  • Senatore Gambero
  • ******
  • Post: 1.273
  • Chi parla poco dice tanto...
    • Mostra profilo
Re: Form MDI
« Risposta #28 il: 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 ;)

Offline perseo

  • Maestro Gambero
  • ****
  • Post: 264
    • Mostra profilo
Re: Form MDI
« Risposta #29 il: 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]
« Ultima modifica: 09 Novembre 2010, 13:50:15 da perseo »