Come
lavorare con schede
a pagine multiple
in Visual dBASE 7.x
Ken Mayer, dBVIPS
Lo scopo di questo documento è discutere delle schede a pagine multiple ed il loro uso. Pur essendo un argomento abbastanza semplice ad un neofita di Visual dBASE può creare un po di confusione.
Cos'è una scheda multi pagina | Cambiare pagine con i Tabbox | Codice esempio | |
Concetti base | Cambiare pagine con i Pulsanti | Sommario |
Cose'
una scheda a pagina multipla?
E una singola scheda in cui i dati (informazioni) sono
disposti in più pagine (di fatto non ci sono pagine o oggetti
pagina da gestire N.d.T.). Nel mondo dBASE/DOS questo è stato
realizzato con schede multiple. In Visual dBASE questo può
essere fatto con una scheda. (anche se non è una buona idea
creare una scheda di 10 pagine in Visual dBASE, questo porta
inevitabilmente all'esaurimento delle risorse di Windows.)
Ci sono almeno tre metodi che possono essere usati per creare e lavorare con schede a pagina multipla:
usare i separatori (Tabs);
usare i pulsanti;
usare altri mezzi tramite la programmazione.
Questo documento tratterà i primi due metodi. Non
parleremo dell'utilizzo dell'oggetto
Notebook, che è un controllo visuale che può essere usato in
aggiunta alle discussioni qui mostrate di un oggetto container a
pagine multiple (non di una scheda).
Non lasciare che questo
documento limiti la tua immaginazione. Visual dBASE è un potente
strumento di sviluppo che offre notevoli possibilità di
raggiungere lobiettivo in modi diversi, rispetto a quelli
discussi in questo documento.
Le schede e gli oggetti di Visual
dBASE hanno
una proprietà che non esisteva in dBASE 5.0 per Windows o nei
prodotti dBASE/DOS: PageNo.
Questa proprietà è vitale per il compito che dobbiamo
affrontare.
La proprietà PageNo riferita ad una scheda indica il numero
della pagina attiva. Questo per esempio, può essere cambiato da
programma con l'istruzione:
form.PageNo := 2
Gli oggetti hanno una proprietà PageNo che indica la pagina sulla quale appariranno. Ad esempio, un entryfield che è stato assegnato alla pagina 2, avrà la sua proprietà pageNo definita dalle seguenti linee:
class ENTRYFIELD1(parentObj, name) of ENTRYFIELD(parentObj, name)
with (this) height = 1 left = 1.2857 top = 0.7273 width = 10.7143 metric = 0 // Caratteri pageno = 2 endwith
endclass
Importante: Poiché la pagina di default di
qualsiasi scheda è pagina 1, qualunque oggetto sarà messo su
pagina 1. Normalmente non "riverseremo fuori" la
proprietà pageNo riferita a pagina 1.
La proprietà PageNo può essere utilizzata come
ogni altra proprietà. Comunque, nella maggior parte casi puoi
lasciare un oggetto specifico su una pagina specifica.
In alcuni casi si può volere che un oggetto appaia su tutte le
pagine di una scheda. Questo risulta tanto facile quanto il
resto, se impostiamo la proprietà PageNo a 0 (zero),
loggetto apparirà su tutte le pagine della scheda.
Metodo 1 - Cambiare pagine con TabBox
Quando la scheda é in esecuzione l'utente
dovrà avere la possibilità di spostarsi da una pagina
all'altra.
Il controllo TabBox di Visual dBASE è progettato per permetterci di creare ed utilizzare facilmente schede a pagine multiple.
NOTA: Il controllo Tabbox non si limita a lavorare con schede che hanno più
pagine. E' possibile avere controlli Tabbox multipli
sulla stessa scheda, con associato vario codice per fare altre cose...
Ancora una volta, Visual dBASE è un potente pacchetto linguaggio/software e se
si può immaginare un "uso" per
il controllo Tabbox, ci sono notevoli possibilità di realizzare ciò
che abbiamo immaginato...
In modalità progettazione nella pagina "Standard" della "Tavolozza Componenti", troverai un'icona per il TabBox:
Se clicchiamo sul componente Tabbox e lo trasciniamo su una scheda, un singolo "separatore" sarà messo sul fondo della scheda.
Il TabBox per default dovrebbe impostare a 0 (zero) la sua proprietà PageNo. Se cosi non fosse impostiamola adesso. Se vogliamo possiamo assegnare un nome al TabBox, l'impostazione predefinita è di solito TabBox1 ed è quello che questo documento presumerà. Ovviamente se ne abbiamo bisogno possiamo impostare i nomi per i separatori. Se guardiamo nella proprietà DataSource, dovremmo vedere:
ARRAY {"TabBox1"}.
Questo porta ad un argomento interessante che
esamineremo brevemente (gli array sono trattati con maggiori dettagli
in altri documenti HOW TO):
Array letterali
Il tipo array predefinito per un TabBox è chiamato "Array letterale". Questo array può essere definito con il disegnatore visuale. Una cosa circa questo tipo di array che un po sconcerta è che non ha un nome. Non esiste modo per riferirsi al suo contenuto. Nella maggior parte dei casi quando usiamo un TabBox, esso é assolutamente eccellente! Comunque, non dobbiamo usare un array letterale se non lo vogliamo. Possiamo usare invece un array standard di Visual dBASE (uno con un nome), la sola ragione che mi viene in mente circa il fatto che si vuole usare un array standard é se si ha bisogno di conoscere il testo del separatore dove attualmente si trova il cursore, ma ci potrebbero essere facilmente altre ragioni...
I disegnatori visuali ci permettono di costruire il nostro array attraverso una "finestra di dialogo" davvero elegante. Per visualizzare questa "finestra" tramite il modulo "Ispezione" clicchiamo sul pulsante della proprietà datasource del tabbox,
compare una finestra di dialogo con la definizione dell'array corrente
clicchiamo sul pulsante ed apparirà la finestra di dialogo "Genera array"
Possiamo aggiungere, rimuovere e riordinare le "etichette" dei separatori piuttosto facilmente con questa finestra di dialogo e quando abbiamo finito il pulsante "OK" metterà i contenuti dell'array sulla scheda. Il numero di separatori (tabs) sul tuo tabbox corrisponde al numero di elementi nell'array.
L'evento OnSelChange
In Ispezione (selezionando il tabbox) se clicchiamo sulla pagina degli eventi, si vedrà questo evento. Clicchiamoci su. Possiamo aggiungere del codice per essere eseguito con un codeblock, o possiamo impostare qualcosa di più sofisticato (una funzione). Io raccomando di impostare qualcosa di più sofisticato, tramite una procedura. Questo è facilmente realizzabile tramite un semplice clic sul pulsante nel modulo "ispezione" relativo a questo evento. Impostazione scheda attiverà l'editor di sorgenti e metterà un'intestazione per l'evento e subito dopo potremo inserire il nostro codice:
PROCEDURE Tabbox1_onSelChange
In questa procedura si può impostare il "PageNo" della scheda con il corrente numero di separatore (elemento). La proprietà che da il numero del separatore corrente è: CurSel.
La procedura potrebbe somigliare:
PROCEDURE Tabbox1_onSelChange
form.PageNo := this.CurSel
La ragione per mettere questa istruzione nel codice che gestisce l'evento è che vogliamo ottenere qualcosa di più sofisticato (ad esempio: effettuare un controllo per vedere quale pagina si é adesso, impostare specifici valori per gli oggetti sulla scheda, cambiare il rowset della scheda , molte altre possibilità saltano in mente...).
Metodo 2 Cambiare pagine con i pulsanti
Mentre la maggior parte delle nuove applicazioni usa i TabBoxes per cambiare pagina, un altro metodo piuttosto efficace è usare i pulsanti. Se mettiamo un paio di pulsanti su una scheda avremo bisogno di impostare gli eventi OnClick per gestire gli spostamenti di pagina. Ciò è abbastanza semplice (esempio sotto).
Come dicevamo sopra dovremmo impostare l'evento OnClick per entrambi i pulsanti, ma prima ci sono alcune altre cose che potrebbe essere necessario fare. Si consiglia di agganciarsi ad un evento piuttosto che usare un codeblock.
Un suggerimento molto semplice é quello di agganciarsi all'evento(On_click) dei pulsanti, per gestire lincremento e il decremento del numero di pagina e successivamente chiamare unaltra routine per gestire ciò che può essere necessario fare, quando si cambia pagina (come impostare il fuoco alloggetto adatto sulla pagina adatta).
Il seguente codice di esempio presume che i pulsanti siano chiamati "PagSucc" e "PagPrec":
PROCEDURE PagSucc_OnClick
form.PageNo++ // incrementa il numero pagina
class::MyPageChange() // procedura per gestire altre istruzioni necessarie
PROCEDURE PagPrec_OnClick
form.PageNo-- // decrementa il numero pagina
class::MyPageChange() // come sopra
La descrizione dell'evento OnClick per i pulsanti sarebbe allora (nel modulo Ispezione della Proprietà onclick, pagina dei Metodi): class:: PagSucc_OnClick oppure: class::PagPrec_OnClick.
Quando navighiamo attraverso una scheda con diverse pagine, potremmo avere un problema se il codice che gestisce il pulsante non è "appropriato".
Che cosa accade se siamo su pagina 1, e l'utente clicca sul pulsante "Pagina Precedente" ?
Non esiste pagina 0 (o meglio esiste, ma di solito è abbastanza brutta perché contiene tutti gli oggetti sulla scheda).
Che cosa succede se siamo sull'ultima pagina, e l'utente clicca sul pulsante "Prossima Pagina" ?
Se non c'è nessuna pagina definita verrà visualizzata sulla scheda una pagina bianca.
Questo può essere gestito nella procedura MyPageChange abilitando o disabilitando i pulsanti:
PROCEDURE MyPageChange if form.PageNo == 1 form.PagPrec.Enabled := false // disabilita il pulsante else form.PagPrec.Enabled := true // abilita il pulsante endif if form.PageNo == 3 //si presume che pagina tre sia l'ultima form.PagSucc.Enabled = false // disabilita il pulsante else form.PagSucc.Enabled = true // abilita il pulsante endif
Queste due istruzioni if/endif possono essere
raffinate un po usando la funzione lIF() di dBASE, ma si è voluto mostrare la versione del codice più lunga per amore di
chiarezza.
Sotto c'è la versione ridotta:
form.PagPrec.Enabled := iif(form.PageNo==1,false,true)
form.PagSucc.Enabled := iif(form.PageNo==3,false,true)
SUGGERIMENTO: Per evitare di modificare il codice tutte le volte che si deve cambiare il valore che indica l'ultimo numero di pagina, si può usare il metodo della scheda pageCount() quale numero dellultima pagina:
form.pageCount() // numero di pagina più alto usato su una scheda
ed usarlo nel codice descritto sopra, prova:
form.PagSucc.Enabled := iif(form.PageNo==form.pageCount(),false,true)
Il vantaggio che ne traiamo risiede nel fatto che se dovessimo in un secondo tempo aggiungere/rimuovere pagine dalla scheda, non si deve aggiornare il codice che le gestisce.
La procedura MyPageChange
La procedura MyPageChange è dove
"diciamo" a Visual
dBASE quello che deve fare quando cambia il numero di pagina.
Per
esempio se volessimo impostare il fuoco sul primo oggetto di ciascuna
pagina:
PROCEDURE MyPageChange
// se usiamo i pulsanti per muoverci tra le pagine: form.PagPrec.Enabled := iif(form.PageNo==1,false,true) form.PagSucc.Enabled := iif(form.PageNo==form.pageCount(),false,true)
// gestisce l'impostazione del fuoco e qualsiasi cosa che potrebbe essere // necessario fare quando cambia il numero di pagina.
do case case form.PageNo == 1 form.entryfield1.setfocus() // entryfield1 ottiene il fuoco case form.PageNo == 2 form.entryfield43.setfocus() // entryfield43 della pagina 2 ottiene il fuoco case form.PageNo == 3 form.entryfield71.setfocus() // come sopra endcase
Possiamo voler effettuare un processo di convalida dei nostri entryfields e degli altri oggetti collocati su di una pagina, quando ci si sposta di pagina. Questo può essere gestito come nella procedura MyPageChange.
Il codice potrebbe verificare qualche cosa di simile:
if form.Tabbox.Cursel # 1 and empty(form.entryfield1.value) MsgBox('Devi inserire il codice cliente prima!') // Avviso This.CurSel := 1 // ritorna a pagina 1 form.entryfield1.SetFocus() // dai il fuoco all'entryfield1 else form.pageno := this.cursel // altrimenti cambia pagina endif
Problemi potenziali
Non è probabilmente una buona idea aggiungere dati in altre tabelle su altre pagine se il "master record" sulla prima pagina non sia stato salvato. Una possibile soluzione è impedire agli utenti di cambiare pagina tramite la disabilitazione della proprietà enabled di un tabbox (o se usiamo i pulsanti per navigare, i pulsanti coinvolti) fino a che non si salvi il record. Nota che tramite gli oggetti OODML database e query di Visual dBASE 7, questo non é più un grosso problema come lo era nelle versioni precedenti di VdBASE.
In modalità progettazione, se salviamo la scheda ed il numero di pagina è diverso da 1, la prossima volta che manderemo in esecuzione la scheda, essa visualizzerà la pagina selezionata quando abbiamo eseguito il salvataggio della scheda. Per risolvere questo problema si può aggiungere il seguente codice al metodo onOpen della scheda
PROCEDURE form_onOpen
form.Tabbox1.curSel := 1 // questo attiverà levento onSelChange del tabbox
// qualsiasi altro codice che hai bisogno
Brevemente, la flessibilità di Visual dBASE è tale che si può trovare probabilmente una serie di ragioni per usare schede multi pagina. Ciò si può realizzare usando le tecniche qui mostrate, possiamo da programma spostarci su una "pagina nascosta" per visualizzare informazioni utente sotto circostanze specifiche, ecc.. come sempre, se possiamo pensare a fare qualcosa, le probabilità che puoi farlo in Visual dBASE sono notevoli.
Per assistenza specifica per favore usate il Newsgroups di Visual dBASE (vedi: http:// www.dbase2000.com per più dettagli). Per favore non contattate l'autore direttamente tramite la posta elettronica...
Copyright 1998, Kenneth J. Mayer. All rights reserved.
Nel file .ZIP ci sono due semplici schede le quali mostrano alcune delle tecniche menzionate in questo documento. Questi sono "MULTIPG1.WFM" e "MULTIPG2.WFM." Questi file contengono esempi piuttosto semplici, ma riflettono i concetti mostrati in questo documento.
EoHT: MULTPAGE.HTM -- 11/02/1998 -- KJM