Newsgroup: it.comp.lang.delphi
Titolo: Problema con TPageControl

Ho un simpatico TPageControl nella mia FORM.
Ho una procedura siffatta:
--- procedure TfrmMain.PCShowPage(const i : integer);
// dato un intero, mi rende TabVisible solo il TabSheet che ha un index
// corrispondente. Per farlo me li scorre tutti e li controlla con i in
// questo modo:
// ---------------------------
for j := 0 to Pager.PageCount-1 do
    begin
    if j = i then
        Pager.Pages[j].TabVisible := True
    else
        Pager.Pages[j].TabVisible := False;
    end;
Pager.ActivePageIndex := i;
// ---------------------------
Non FUNZIONA!
Ricevo questo errore:
---------------------------
Debugger Exception Notification
---------------------------
Project MyProgram.exe raised exception class EListError with message
'List index out of bounds (5)'. Process stopped. Use Step or Run to
continue.
---------------------------
OK   Help
---------------------------
Come mai?
B.

 Come mai?
Il tuo codice funziona benissimo, o almeno non ho avuto problemi 
nell'eseguirlo. Non vorrei che il problema si annidasse altrove.
Fai il debugging "passo per passo" per verificare qual è il punto in 
quel metodo - ammesso che sia quello che va in errore - in cui l'indice 
o un'altra variabile usata per l'indicizzazione esce dal range di valori 
accettabili.
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)
     Non hai la possibilità di scaricare Turbo Delphi Explorer?
     Te lo spedisco io!! [
http://www.marco.breveglieri.name/?p=48
]

 B.
Sei sicuro che il parametro i sia nel range 0..Pager.PageCount-1 ?
Io, per sicurezza, scriverei il codice in questo modo:
 if i in [0..Pager.PageCount-1]
  then begin   
    for j := 0 to Pager.PageCount-1 do
       Pager.Pages[j].TabVisible := j = i;
    Pager.ActivePageIndex := i;
   end
  else
   Application.MessageBox('Indice i fuori dal range');
così riesci a capire se il problema è provocato dal parametro.
PS: il codice è stato scritto 'di getto' senza alcun tipo di
verifica, ed è probabile che contenga qualche errore.
Giuseppe


A me invece non funziona, ho fatto il debug e l'errore sta proprio
nell'esecuzione della riga
--- Pager.Pages[j].TabVisible := True
al secondo ciclo, quando j = 1, dato i = 0
Sembrerà strano, ma mi sono accorto che è come se la proprietà
TabVisible, dal secondo TabSheet in poi, non si vista e l'errore dato è
-----
Project MyProgram.exe raised exception class EListError with message
'List index out of bounds (5)'. Process stopped. Use Step or Run to
continue.
-----
Infatti se io, per sfizio, metto tutti i TabSheet.TabVisible a False a
designtime, dopo tutto funziona bene, ma se sono True a design time si
verifica l'errore.
So che tutte le proprietà, a parte quelle di default, vengono scritte
nel file DFM di una form... non so se c'entra qualcosa.
Io ho risolto così e funziona qualunque sia la situazione a designtime,
come è giusto che sia:
for j := 0 to Pager.PageCount-1 do
   begin
   //MISTERO DEI MISTERI >>
   try
        Pager.Pages[j].TabVisible := j = i
   except
        ;
   end;
   end;
   //FINE MISTERO DEI MISTERI >>
Ciao a tutti.

 come è giusto che sia [...]
Secondo me, il debugging non è stato fatto accuratamente e il problema 
risiede da qualche altra parte, poiché - come dicevo prima - l'errore si 
verifica quando tenti di impostare la visibilità del Tab ad un valore 
nel caso in cui le variabili intere di riferimento siano uguali, ed è 
ciò che in effetti il programma esegue, stando alla tua descrizione, 
salvo però il fatto che le variabili non sono uguali.
Come si dice in questi casi, "c'è qualcosa che tocca...". ;-)


    end;
Ma quindi hai risolto con la questa versione (effettivamente più 
corretta) del codice?
-- 
Jax

 Pager.ActivePageIndex := 0;
il problema dovrebbe risolversi.
In realtà io ho scritto una piccola procedura che scorre le varie
pagine, cercando la prima visualizzata e questa viene selezionata come
attiva.

Jax ha scritto:

Ho risolto in pratica. Ma mi rimane il dubbio di come mai non posso
rendere visibili i Tabsheet già in designtime.
L'eccezione che viene sollevata proprio non la capisco.

 L'eccezione che viene sollevata proprio non la capisco.
Se vuoi rendere disponibile il tuo codice memorizzando un sorgente di 
esempio in qualche sito che offre un servizio di "storage", potremmo 
scaricarlo e dargli un'occhiata. Ci sono forse elementi che vengono 
trascurati o non è possibile dedurli dal testo del messaggio.


Alessandro ha scritto:

GRANDEEEEEEEEEEEEEEEEEEEEEE!
Il solo ed unico Alessandro ha risolto il problema!
Anche se non capisco perché (ma questo oramai è solo accademico) messa
in questo modo la procedura funziona:
procedure TMyType.PagerPageShow(const i : integer);
var j : integer;
begin
Pager.ActivePageIndex := 0;
for j := 0 to Pager.PageCount-1 do
   Pager.Pages[j].TabVisible := j = i;
Pager.ActivePageIndex := i;
...
end;
Faccio notare che:
1. Prima del ciclo for ActivePageIndex era = 3
2. Mi dava errore
3. Allora lo metto come default sempre a 0
4. Ciclo sui Tabsheet
5. Trovo i, lo rendo visibile
6. Setto ActivePageIndex su i
Funziona!
Sono commosso.
Grazie.

 in questo modo la procedura funziona:
Mi verrebbe da ipotizzare che non è possibile impostare a /TabVisible/ a 
False per le schede visualizzate, e che per un caso fortuito il tuo 
codice funzionasse perché io non avevo selezionato come attiva, a 
designtime, una scheda diversa dalla prima, cioè quella con indice zero.
Ovviamente, sono solo supposizioni: non ho la possibilità di verificarlo 
al momento, ma tu dovresti fare presto, commentando la riga che hai 
aggiunto e provando i due casi.


 in questo modo la procedura funziona:
Per quello che ho capito io, il problema riguarda proprio la pagina che
a designtime viene lasciata come predefinita.
Se la forzatura delle pagine visualizzate avviene durante l'evento
create (ma forse anche show e activate) del form, probabilmente viene
tentato successivamente dal sistema di forzare la pagina attiva
predefinita nel designtime e questo causa l'errore di List index out of
bounds (e qui credo centri un indice relativo a pagine visualizzate e
no che non corrisponde).
Come già scritto, io utilizzo una piccola procedura che viene eseguita
automaticamente nell'evento create di ogni form (uso sempre un
discendente di form come base per i miei progetti, mai TForm
direttamente) che va a selezionare la prima TTabSheet disponibile e
visibile della TPageControl, dando anche un certo ordine a tutto il
progetto.