Gambas-it

Gambas3 => Programmazione => Topic aperto da: perseo - 12 Novembre 2010, 12:02:47

Titolo: Keypress e Focus
Inserito da: perseo - 12 Novembre 2010, 12:02:47
Ciao a tutti.

Volevo sapere se sia possibile attraverso l'evento Keypress di una txtbox (di un gruppo "txt") di cambiare il tasto premuto con un altro. Nello specifico vorrei far avanzare la textbox al controllo successivo quando viene premuto il tasto Invio (o Return), esattamente come accade per il tasto Tab.

Ho provato a scrivere nell'evento Keypress...
If Key.Code = Key.Return Then Last.Next.Setfocus

Ma non va bene... io non voglio dare il focus ad un altro controllo, voglio solo uscire da questo passando attraverso il suo evento _LostFocus (dive c'è scritto cosa fare)... e credo che il tasto Tab funzioni così.
Titolo: Re: Keypress e Focus
Inserito da: doublemm - 12 Novembre 2010, 15:50:22
Citazione
Nello specifico vorrei far avanzare la textbox al controllo successivo

Citazione
Ma non va bene... io non voglio dare il focus ad un altro controllo, voglio solo uscire da questo passando attraverso il suo evento _LostFocus

Non capisco se  vuoi dare il focus ad un altro controllo oppure no.

Comunque :
Codice: gambas [Seleziona]

PUBLIC SUB TextBox1_KeyPress()

  IF Key.Code = Key.Return THEN
    TextBox2.SetFocus
    TextBox1_LostFocus()
  ENDIF
END

PUBLIC SUB TextBox1_LostFocus()

  Label1.Text = "Eseguito textbox1_lostfocus"

END


se non vuoi che il focus vada su textbox2 tralasci la riga textbox2.setfocus. Il focus deve andare per forza da qualche parte.

Titolo: Re: Keypress e Focus
Inserito da: perseo - 12 Novembre 2010, 16:11:10
Mi spiego meglio...

Ho una serie di controlli inseriti in due container differenti. In gerarchia è così:
Primo Container:
- label1
- txtbox1
- label2
- txtbox2
- label3
- txtbox3
- labelGV
- GridView

Secondo Container:
- label4
- txtbox4
- label5
- txtbox5
- ecc...

Nel passaggio dalla ultima txtbox3 del 1°container --> alla txtbox4 del 2°container sono dovuto intervenire da codice (sull'evento _LostFocus), altrimenti c'era una GridView di mezzo...

Tutte le txtbox fanno parte di un gruppo "txt", quindi devo usare Last... ma se nell'evento _Keypress() del gruppo "txt" scrivo Last.Next.SetFocus... il focus non va...

[edit]
Ho scoperto che il Focus in realtà va al successivo, ma sul label! Perché con il tasto <Tab> invece mi va direttamente al txtbox successivo (saltando il label), mentre con .next mi va sul label (che sta prima del txtbox)?
A questo punto opterei per accantonare tutti i label da una parte, ma mi sembra una soluzione spartana, oppure di scrivere tutti i passaggi a mano da codice.   :rolleyes:
Per risolvere devo scrivere tutto il percorso a mano, o c'è possibilità di farlo in automatico?  ???
Titolo: Re: Keypress e Focus
Inserito da: Ceskho - 12 Novembre 2010, 18:38:39
A questo punto opterei per accantonare tutti i label da una parte, ma mi sembra una soluzione spartana, oppure di scrivere tutti i passaggi a mano da codice.   :rolleyes:
Per risolvere devo scrivere tutto il percorso a mano, o c'è possibilità di farlo in automatico?  ???

L'ordine gerarchico degli elementi in un form o in un contenitore può essere modificato cambiando la tab da Proprietà a Gerarchia....
Titolo: Re: Keypress e Focus
Inserito da: perseo - 12 Novembre 2010, 19:29:54
Ho una serie di controlli inseriti in due container differenti. In gerarchia è così: ...

Nel post precedente ho elencata la sequenza in gerarchia...

Il problema è che <Tab> trasferisce il focus verso la successiva txtbox (o comunque un controllo di inserimento dati), mentre il metodo .next trasferisce il focus al controllo successivo, qualunque sia (anche una label). Quindi mi chiedevo se fosse possibile restituire la pressione del tasto <Tab> quando si preme <Return>... In questo modo simulerei il <Tab> ...ed il focus procederebbe al successivo controllo txtbox.
Titolo: Re: Keypress e Focus
Inserito da: dex - 12 Novembre 2010, 21:40:00
Ho notato anche io che tab utilizza un suo metodo (in base alla creazione) per memorizzarsi il suo index, non so se si può modificare da codice.

Per il tuo problema è semplice intercetti l'evento KeyPress e ci metti un select per passare i focus
Esempio: primo select intercetta i tasti invio, return e freccia giu e sposta in basso il focus, il secondo select intercetta freccia su e sposta in alto il focus.

A dimenticavo tutti i controlli fanno parte di un gruppo (texA) e a ogni controllo ho messo un numero nel tag, nel gruppo ci puoi mettere anche controlli diversi (label, text, button ecc..)
In alternativa se non vuoi creare ne gruppo ne tag intercetti l'evento Keypress di ogni singolo controllo e fai dare il focus a quello successivo

Codice: [Seleziona]
PUBLIC SUB TexA_KeyPress()
 
  SELECT Key.code
      CASE Key.Enter, Key.Return, Key.down
     
         SELECT (LAST.tag)
           
            CASE 2
               TextBox3.SetFocus
            CASE 3
               TextBox4.SetFocus
            CASE 4
               TextBox5.SetFocus
            CASE 5               
               TextBox9.SetFocus 
            CASE 9
               TextBox10.SetFocus 
            CASE 10
               TextBox11.SetFocus 
            CASE 11
               TextBox12.SetFocus 
            CASE 12
               TextBox13.SetFocus 
            CASE 13
               TextBox14.SetFocus 
            CASE 14
               TextBox15.SetFocus 
            CASE 15
               TextBox26.SetFocus 
            CASE 16
               TextBox17.SetFocus 
            CASE 17
               TextBox18.SetFocus 
            CASE 18
               TextBox19.SetFocus 
            CASE 19
               TextBox20.SetFocus 
            CASE 20
               TextBox21.SetFocus 
            CASE 21
               TextBox22.SetFocus
            CASE 22
               TextBox23.SetFocus
            CASE 23
               TextBox24.SetFocus
            CASE 24
               TextArea1.SetFocus
            CASE 25
               TextArea1.SetFocus
            CASE 26
               TextBox16.SetFocus
                                         
         END SELECT
         
       CASE Key.up
         
         SELECT (LAST.tag)
           
            CASE 3
               TextBox1.SetFocus
            CASE 4
               TextBox3.SetFocus
            CASE 5
               TextBox4.SetFocus                     
                               
            CASE 9
               TextBox5.SetFocus                     
            CASE 10
               TextBox9.SetFocus                     
            CASE 11
               TextBox10.SetFocus                     
            CASE 12
               TextBox11.SetFocus                     
            CASE 13
               TextBox12.SetFocus                     
            CASE 14
               TextBox13.SetFocus                     
            CASE 15
               TextBox14.SetFocus                     
            CASE 16
               TextBox26.SetFocus                     
            CASE 17
               TextBox16.SetFocus                     
            CASE 18
               TextBox17.SetFocus                     
            CASE 19
               TextBox18.SetFocus                     
            CASE 20
               TextBox19.SetFocus   
            CASE 21
               TextBox20.SetFocus
            CASE 22
               TextBox21.SetFocus   
            CASE 23
               TextBox22.SetFocus
            CASE 24
               TextBox23.SetFocus
            'CASE 25
               'TextBox24.SetFocus
            CASE 26
               TextBox15.SetFocus           
         END SELECT 
   
   END SELECT

END
Titolo: Re: Keypress e Focus
Inserito da: Picavbg - 12 Novembre 2010, 22:37:15
Ho una serie di controlli inseriti in due container differenti. In gerarchia è così: ...

Nel post precedente ho elencata la sequenza in gerarchia...

Il problema è che <Tab> trasferisce il focus verso la successiva txtbox (o comunque un controllo di inserimento dati), mentre il metodo .next trasferisce il focus al controllo successivo, qualunque sia (anche una label). Quindi mi chiedevo se fosse possibile restituire la pressione del tasto <Tab> quando si preme <Return>... In questo modo simulerei il <Tab> ...ed il focus procederebbe al successivo controllo txtbox.
Purtroppo Gambas non permette di forzare in Key.code ilcarattere esadecimale distintivo di alcun tasto, di conseguneza, nemmeneno "TAB".
Citazione
Se provi a farlo ti segnala ERRORE con la dicitura che Key.Code é disponibile solamente in lettura.
Non sapevo che il metodo _new passa al successivo controllo a prescindere se esso sia una label o un TextBox o un'altro oggetto qualsiasi. Puoi provare a richiamare nella Labelx_GotFocus la corrispondente Label_lostFocus per fargli eseguire il passaggio alla successiva TextBox.
Non ti consiglio nemmeno il metodo ".SetFocus" perché quando ne devi inserire tanti, alla fine finisci per scombinare a Gambas la naturale sequenza gestionale degli oggetti contenuti in uma Form. Io l'ho fatto e purtroppo lo faccio ancora perché non ho scoperto un metodo più sicuro ed infatti Gambas salta da una procedura all'altra dei controlli in maniera sconclusionata e spesso sono costretto ad eseguire voli pindarici per ricomporre l'ordine che desidero ottenere.
In VB era normalissimo passare il controllo ad un oggetto diversio della Form con ".setFocus", senza avere brutte sorprese. Però almeno con Ganmbas sto riuscendo a portare avanti il mio programma, mentre VB, per altri motivi, me lo ha impedito.
Titolo: Re: Keypress e Focus
Inserito da: milio - 12 Novembre 2010, 22:58:53
Work in Progressssss.....
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 00:41:33
Siccome non sono riuscito a trovare un qualcosa per scombinare da codice questo benedetto ordine dei controlli in un form, ho fatto una piccola classe statica che da la possibilità appunto di riordinare a piacimento il focus degli oggetti da codice...

La classe si chiama Sequence ed e' una classe di tipo statica.

Si utilizza in questo modo:

Nella Sub _new, o nell'evento Form_Open:

  Sequence[ME].Move(ControlName As String, Optional Previous As String)

Il controllo precedente,se non viene dichiarato, fa passare l'oggetto alla prima posizione.

Es. (compreso nei sorgenti):

Codice: vb.net [Seleziona]
  With Sequence[Me]
    .Move(Me.SpinBox1.Name)
    .Move(Me.TextBox1.Name, Me.SpinBox1.Name)
    .Move(Me.Button2.Name, Me.TextBox1.Name)
    .Move(Me.Button1.Name, Me.Button2.Name)
    .Move(Me.TextBox2.Name, Me.Button1.Name)
  End With


naturalmente non si e' obbligati a rifare completamente la gerarchia, ma si puo' solamente spostare quello che serve ;)

Ho aggiunto anche qualche altra diavoleria per gestire la classe:

Sequence[Me].AddIgnoreClass(ClassName As String)

    Questa sub serve a escludere dalla gerarchia tutti gli oggetti che fanno parte di una medesima classe genitore. Di default (come in Gambas d'altronde) ho gia escluso Label, TextLabel e tutti i tipi di contenitori.

Sequence[Me].AddKey(Key As Integer, Optional Back As Boolean)

    Questo metodo serve ad aggiungere Key.code che fanno spostare il focus degli oggetti. L'opzione Back settata a True fe retrocedere il Focus (vedi BackTab)


Property Enabled As Boolean

    Settata di default a True. Se False abilita la gerarchia originale del Form.


Spero che a qualcuno possa servire ;)
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 00:58:22
Non so se odiarti o adorarti...  ;D

Sono stato tutta la sera a scrivere una SUB demente da richiamare ad esempio agli eventi _Keypress... e quando la stavo per postare ho letto il tuo intervento!

Sei eccezionale! Me la scarico subito... e la provo immediatamente!  :2birre:


PS: giusto per la cronaca... questa era la Sub che avevo scritto applicabile a "gruppi" di controlli...  :-[

Codice: vb.net [Seleziona]

Public Sub myfocus(tasto As Integer, objPrev As Control, objNow As Control, objNext As Control)
  If Last.name = objNow.name Then
    Select Case tasto
      Case Key.Return, Key.Down, Key.Enter, Key.Tab
        Stop Event
        Try objNext.SetFocus
        Try objNext.SelectAll
      Case Key.BackTab, Key.Up
        Stop Event
        Try objPrev.SetFocus
        Try objPrev.SelectAll
    End Select
  Endif

  Catch
    Message("Si è verificato un errore nella pressione del tasto!")
End


PPS: le due ore le ho impiegate a capire se potevo addirittura  ;D creare una stringa con i nomi in sequenza dei controlli... e poi far fare tutto alla SUB.
Mi sono arenato sul passaggio da nome_controllo As stringa --> nome_controllo As Control.  ???

PPPS: cmq alla fine mi sono anche reso conto che la cosa sarebbe stata applicabile ai controlli txt, ma le Searchbox ho visto che sono restie all'evento _Keypress (sui tasti: Key.Return, Key.Enter, Key.Up, Key.Down, ecc.), e si bloccava la sequenza.  :-\
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:04:09
Citazione
Non so se odiarti o adorarti... 

Sono stato tutta la sera a scrivere una SUB demente da richiamare ad esempio agli eventi _Keypress... e quando la stavo per postare ho letto il tuo intervento!
:P :P :P :P

anch'io e' da tempo che mi dicevo che dovevo scriverla una classe del genere :)

Fammi sapere se funzia con le searchbox...
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:06:12
E' possibile caricarla direttamente in Gambas... tipo come facciamo con i componenti?

Oppure devo importare tutte e due le classi: Sequenza e _Sequenza nel mio progetto?
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:09:29
Vuoi dire se e' un componente?

Bhe basta fare le dovute modifiche...

Le classi devono viaggiare assieme...

C'e' comunque un'altra alternativa: Progetto ---> Proprietà ---> Librerias  ---> Add e ti scegli l'eseguibile Sequence.gambas contenuto nella cartella dei sorgenti
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:16:58
Mi va in errore...

_Sequence.AddIgnoreClass.41
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:20:58
L'hai usata nell'esempio o con searchbox?
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:27:17
L'ho usata nell'esempio e funziona...

Poi ho importato le due classi Sequence e _Sequence nei miei sorgenti e mi va in errore.
L'ho applicata così nel _new di una Form secondaria (non nel FMain):

With Sequence[Me]
    .Move(Me.GridView1.Name)
    .Move(Me.GridView1.Name, txtCognome.Name)
 End With  

PS: non ho scritto altro.. tipo dichiarazioni, ecc.
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:30:16
Ma che errore ti da?
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:33:07
Null object
_Sequence.AddIgnoreClass.41
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:38:11
capito

Togli nella classe _Sequence alla riga 36 Me.AddIgnoreClass("TextLabel")

E' una classe che c'e' solo in Qt e tu usi Gtk....
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:39:36
devo comunque fare una modifica per gli oggetti compositi tipo ValueBox (e penso anche i miei)... quando entra all'interno del controllo non ne viene piu' fuori  :o
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:43:30
Mi correggo TextLabel c'e' anche in gtk... allora non so quale sia il tuo problema
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:43:43
Sto usando QT4 e comunque l'avevo già tolta (sia textlabel che label) e quando eseguo mi dava un altro errore... alla riga66:

Null object
_Sequence.Move.66

PS: però il tuo esempio funziona... non capisco proprio.
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 01:46:52
Mi puoi postare la tua prova?
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 01:55:43
Allegato...

la prova la trovi nella FMain.
Titolo: Re: Keypress e Focus
Inserito da: milio - 13 Novembre 2010, 02:56:45
Ok ho sconvolto tutto, perchè mi dava problemi con oggetti composti da piu' controlli...

Il problema e' che adesso si e' obbligati a passare tutti i controlli presenti nel form, pena l'esclusione dal SetFocus.

Codice: vb [Seleziona]
With Sequence[ME].Order
  .Add(Me.Button1)
  .Add(Me.Button2)
  .Add(Me.TreeView)
End With
Sequence[Me].Enabled = True


Praticamente gli passo un Array di oggetti e 'attivo' l'ordine con la proprietà Enabled = True
Titolo: Re: Keypress e Focus
Inserito da: perseo - 13 Novembre 2010, 12:09:02
Mi andava in errore alla riga 70 (quando dal primo tornavo sull'ultimo)...
Avevi scritto: $Order.Max.SetFocus()
L'ho corretto così: $Order[$Order.Max].SetFocus()

Mi sembra già ottimo! Solo che non funziona con le searchbox...

PS: ho scritto una piccola Sub, di nome SequenzaFocus, che setta Sequence.
In pratica anziché scrivere il WITH... .Add(...), .Add(...)... --> ho messo così nel _new():  SequenzaFocus(True, FAccnew, "txtCognome,txtNome,txtSex,txtGG")

E la funzione è questa:
Codice: vb.net [Seleziona]
Public Sub SequenzaFocus(funzionante As Boolean, finestra As Window, sequenza As String)
Dim obj As String[]
Dim i As Integer
obj = Split(sequenza, ";, ")
For i = 0 To obj.Max
  Object.SetProperty(Sequence[finestra], "Order.Add", finestra.obj[i])
Next
End


Il programma non va in errore, ma diventa ...grigio. E devo interrompere l'esecuzione.
Titolo: Re: Keypress e Focus
Inserito da: Picavbg - 14 Novembre 2010, 00:03:51
Siccome non sono riuscito a trovare un qualcosa per scombinare da codice questo benedetto ordine dei controlli in un form, ho fatto una piccola classe statica che da la possibilità appunto di riordinare a piacimento il focus degli oggetti da codice...

Potevi dirmelo, perché ti avrei dato una mano. Non sono capace di realizzare strutture come quelle che crei tu, ma nell'arte di scombinare la sequenza degli oggetti di Gambas non ho eguali!   :rotfl:            Ti avrei proposto di provare il mio programma, però ormai penso che non serva più.
Grazie anche da parte mia per la classe che hai preparato in quattro e quattrotto ed approfitto per scusarmi del ritardo con cui sto rispondendo, ma oggi ho lasciato Gambas ed Internet nel cassetto, perciò hop letto solamente adesso il seguito della discussione. Proverò la tua nuova classe non appena potrò.
Ciao.
Titolo: Re: Keypress e Focus
Inserito da: perseo - 14 Novembre 2010, 00:31:40
Oltre alla questione delle searchbox ho riscontrato un altro problema che non capisco da cosa dipenda...

Nel mio caso, se da una form apro un'altra finestra in showmodal con "sequence" attiva e poi la chiudo... se poi la riapro una seconda volta mi va in errore:

Invalid Object: in class _sequence at line 38 --> dove c'è questo codice --> S.SetFocus()

 :-\