Gambas-it

Archivi (sola lettura) => Programmazione (Gambas 2) => Topic aperto da: jeawrong - 29 Marzo 2009, 23:29:18

Titolo: GridView con header, allineamento testo header?
Inserito da: jeawrong - 29 Marzo 2009, 23:29:18
Salve ragazzi,
premetto che uso Gambas da pochi giorni, da ieri cerco di centrare il testo nell'header di una GridView, senza riuscirci e senza trovare informazioni al riguardo (dovrebbe essere qualcosa di banale, ma non riesco a capire come fare).
Qualche esperto in materia conosce la soluzione?
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: md9327 - 30 Marzo 2009, 02:19:27
Al momento la soluzione non esiste...

La classe GridView attualmente possiede solo la proprietà di modificare l'aspetto delle colonne dati, ma non quello dell'header.

Per modificare la colonna, si può agire sull'oggetto ritornato dalla proprietà Current o sull'array degli elementi ritornati dalla properità Columns.
L'oggetto in questo non può essere istanziato (e quindi non creato, perchè statico), ma possiede alcune proprietà utili allo scopo.

Riguardo l'header, puoi solo decidere se mostrarlo o meno, e vuoi visualizzare la riga in alto, o la colonna laterale (per intenderci quella con indicato il numero di riga), o entrambe. Altre possibilità non sono implementate.

Immagino che questo limita un pochino la possibilità di rendere più gradevole e personalizzato l'aspetto della griglia, e ti dò anche ragione ma, credo che per questa feature tocca aspettare ancora...
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: jeawrong - 30 Marzo 2009, 03:14:10
Grazie, speriamo venga implementato presto allora, effettivamente è una piccola cosa ma che aumenta la piacevolezza del tutto.
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: md9327 - 30 Marzo 2009, 10:41:48
Vero!!!

Diciamo che i componenti grafici di Gambas non sono sicuramente all'altezza di quelli implementati in altri linguaggi più blasonati, ma credo che il lavoro procede, anche se a rilento, a causa della ancor poca diffusione.
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: giulio - 30 Marzo 2009, 12:36:26
Ciao .Puoi farlo con una piccola funzione. Allego un piccolo esempio.
Naturalmente, poi ti devi preoccupare  di gestire l'evento ColumnResize
se vuoi centrare l'header ogni volta che l'utente modifica la larghezza
della colonna. Guarda la funzione AllineaHeader alla fine del codice. Ciao.
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: giulio - 30 Marzo 2009, 12:46:32
EDIT: se non ti piace usare TRY per evitare l'errore del valore iPadding negativo,
modifica così:

Codice: [Seleziona]

IF iPadding < 0 THEN iPadding = 0
GridView1.Columns[0].Text = String$(iPadding, " ") & "First Column width 250" & String$(iPadding, " ")
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: jeawrong - 31 Marzo 2009, 00:12:05
Interessante che (in mancannza di meglio) si possa aggirare l'ostacolo ;) ma per ora preferirei evitare di scrivere ulteriore codice solo per una "mancanza" estetica. In ogni caso grazie mille :))
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Picavbg - 17 Aprile 2009, 15:04:51
Citazione

giulio ha scritto:
Ciao .Puoi farlo con una piccola funzione. Allego un piccolo esempio.
Naturalmente, poi ti devi preoccupare  di gestire l'evento ColumnResize
se vuoi centrare l'header ogni volta che l'utente modifica la larghezza
della colonna. Guarda la funzione AllineaHeader alla fine del codice. Ciao.


Anch'io sono interessato ai problemi di allineamento all'interno della gridview. La mia necessità non è tanto la testata delle colonne, ma l'allineamento di tipo destrorso all'interno delle caselle che destinate a contenere dati numerici. Ho perciò guardato con molta attenzione l'esempio che hai suggerito nel programmino "gridexample" ed ho trasferito la logica nel progetto che sto costruendo. Poichè è possibile che altri possano imbattersi in utilizzazioni come quelle che si stanno trattando in questa discussione, ho pensato di trascrivere le istruzioni che a cui sono arrivato partendeo dal tuo esempio::
Codice: [Seleziona]

DIM $_StriMia AS String
DIM i_LunCasella AS Integer
DIM i_LunTesto AS Integer
DIM i_LunSpazio AS Integer
DIM i_Risult AS Integer

$_StriMia = "9.999,09"
i_LunSpazio = GriView.Font.Width(" ")
i_LunTesto = GriView.Font.Width($_StriMia)
i_LunCasella = GriView.Columns[1].Width
i_Risult = ((i_LunCasella - i_LunTesto) / i_LunSpazio) - 1 'sottraggo uno al risultato per non avere l'ultimo carattere del numero sovrapposto al bordo destro della colonna
GriView[0, 1].text = String$(i_Risult, " ") & $_StriMia

 :-D  
Considerando però che l'utilizzo delle istruzioni di allineamento può essere impiegato per gridview diverse, appartenenti anche a form diverse, sarebbe comodo trasferire il codice,con opportuni adattamenti, in un modulo esterno  Però dal modulo esterno come posso riferirmi ad una gridview? In V.B. era possibile, ma mi pare che in Gambas gli oggetti possono essere referenziati per valore e non per indirizzo, pertanto non posso definire una variabile il cui contenuto sia il riferimento, ora alla grdview1, ora alla gridview2, e così via. Se è così come ricordo, diventerebbe impossibile creare un modulo generalizzato da richiamare all'occorrenza, da una Form.class qualsiasi.
:ciao:  :ciao:
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: giulio - 18 Aprile 2009, 22:33:18
@pica

Ho modificato l'esempio per fare quello che dici tu. E' molto semplice: si mette la funzione in un modulo globale e la si chiama all'occorenza da qualsiasi Form per qualsiasi Grid. Ho aggiunto solo un'altra Form, ma puoi aggiungerne quante vuoi. Comunque guarda il codice: è più facile che spiegarlo. Ciao.

EDIT: naturalmente nell'esempio la funzione usa la stringa del primo
header per calcolare i vari spazi. Sono pigro. Comunque, per il tuo scopo, cioè allineare a destra il testo nelle celle, è chiaro che alla stessa funzione puoi passare anche la colonna e la riga e calcolare così la lunghezza del testo della cella che ti interessa.

Es:.

PUBLIC FUNCTION (hObject as GridView, iRow AS integer, iCol AS integer)

'poi qui ti calcoli la lunghezza del testo della cella con

 iLunghezza = hObject.Font.Width(hObject[iRow, iCol].Text)

'etc etc

END

Nelle Form chiami Global.AllineaHeader(GridView1, 0 ,1) 'per esempio.
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Ceskho - 18 Aprile 2009, 23:45:08
Non potete scrivere la funzione in una classe e inviarla in area download così che tutti possano implementarla facilmente nei loro progetti dotati di gridwier?
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Picavbg - 19 Aprile 2009, 18:26:24
@ giulio

ho scaricato il file che gentilmente hai allegato alla tua rispo, ma all'esecuzione mi da un errore di
Citazione
stack overflow
all'istruzione
Codice: [Seleziona]

 hObject.Columns[0].Text = String$(iPadding, " ") & "First Column width 250" & String$(iPadding, " ")

interna a Global.module.

Comunque penso di avere capito quello che mi ha suggerito, solo che vorrei sapere come hai fatto a tirare fuori dal sacco del..."puparo" (è il marionettista della mia terra di Sicilia) l'oggetto "hObiect"; nel mio sacco non c'era. :hammer:

a parte gli scherzi, ti ringrazio moltissimo. Debbo dirti che ho messo subito in pratica il tuo suggerimento ed in parte ha funzionato; infatti non riesco a capire come l'istruzione
Codice: [Seleziona]

i_LunCasel = hObject.Column[i_NumCol].Width

mi dia un errore di "not an object", eppure l'ho guardata e riguardata tante volte, l'ho anche tascurata e sono andato avanti trasferendo nella mia variabile il valore "100" e sono così riuscito ad ottenere l'allineamento a destra nella casella desiderata della gridview del valore da visualizzare.

Per correttezza trascrivo, qui di seguito le istruzioni impiegate:
Citazione

Nella Form.class di riferimento ho scritto:
Codice: [Seleziona]

DIM $_StriMia AS String
DIM i_ColNUm AS Integer
DIM i_RigaNum AS Integer

$_StriMia = "9.999,09"
i_RigaNum = 0
i_ColNUm = 1
ModuliVari.AllinDx(GriRiepPreMom, i_RigaNum, i_ColNUm, $_StriMia)


mentre nel Global.module ho scritto:
Codice: [Seleziona]

PUBLIC FUNCTION AllinDx(hObject AS GridView, i_NumRg AS Integer, i_NumCol AS Integer, $_Testo AS String)          'Funzione di allineamento destrorso del testo
DIM i_LunCasel AS Integer
DIM i_LunSpazio AS Integer
DIM i_Risult AS Integer
DIM i_LunTesto AS Integer
 
i_LunSpazio = hObject.Font.Width(" ")
i_LunTesto = hObject.Font.Width($_Testo)  
i_LunCasel = hObject.Column[i_NumCol].Width   ««««««  ERRORE (not an object )
i_Risult = (i_LunCasel - i_LunTesto) / i_LunSpazio - 1
hObject[0, 1].text = String$(i_Risult, " ") & $_Testo
END


 Ho anche sostituito il campo dentro le [ ] col corrispondente valore numerico, nel mio caso [1], edl'effetto errore si è ripresentato regolarmente.
___________________________

@ Ceskho:
sembra facile, ma io non saprei da dove cominciare; mi sento troppo piccolo. In ogni caso bisogna prima che la Funzione ... funzioni bene!. :lol:

Ciao a tutti
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: giulio - 19 Aprile 2009, 18:58:03
Per parlare del mio esempio,  a me qui non dà messaggi d'errore tipo
stack overflow. Uso Gambas 2.12 su Slackware con D.E. KDE. Quindi l'esempio
usa le librerie QT. Altro non so dirti. Ora provo il tuo codice e cerco di capire
quell'errore di non object.

P.S. U sacciu socchè u' puparo. Ma stiurnu a ficiru a cronoscalata? aeri mi vinni a viriri i provi. Salutamo a vossia.

P.P.S 'un tu ricu di dunni sugnu, questioni di praivasi :-)
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: giulio - 19 Aprile 2009, 19:15:48
Trovato l'errore:

correggi così:

i_LunCasel = hObject.Columns[i_NumCol].Width


avevi dimenticato la "s" di columns.

Allego il tuo esempio funzionante. E' il tuo codice. Saluti
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Picavbg - 19 Aprile 2009, 23:57:25
Citazione

giulio ha scritto:
Trovato l'errore:

correggi così:

i_LunCasel = hObject.Columns[i_NumCol].Width


avevi dimenticato la "s" di columns.

Allego il tuo esempio funzionante. E' il tuo codice. Saluti


Ahia, alla faccia della 's'! Grazie per la correzione; io non l'avevo proprio vista. :-x

rispo P.S.: Si a ficiru, ma nun sacciu comu finiu.
           
      PS:  Ma, ora comu pozzu durmiri nun sapennu di dunni si tu?
 :-D  :ciao:  :ciao:
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: vuott - 23 Giugno 2012, 14:38:38
Oggi, per Gambas 3 la soluzione c'è:

   https://www.gambas-it.org/wiki/index.php/Centrare_il_testo_nell%27header_di_una_GridView
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Picavbg - 20 Novembre 2013, 00:35:58
Sempre più difficile!
In una casella di GridView devo impegnare tutta la l'ampiezza della casella scrivendo il valore di una variabile all'estrema sinistra e quello di un'altra, sempre nella stessa casella, ma all'estrema destra.

Riprendendo, questa discussione, perchè la funzione Alignment di Gambas non è è applicabile, ho utilizzato la funzione di allineamento "fatta in casa" mediante le seguenti istruzioni:
Codice: gambas [Seleziona]
AllineaCelleGrid = New AllinCelleGriBox(GriTabMovv, iTotRgGri, 2, $NomeVoce, "sx")
          iLun = Len($NomeVoce)
          iLun1 = Len(GriTabMovv[iTotRgGri, 2].Text)
          $StriMia = "Totali pregressi a riporto => SALDO: " & $Valuta & " " & EdtImp.$Imp!          iLun2 = Len($StriMia)
          iDiff = iLun1 - (iLun + iLun2)
          If iDiff > 0 Then
            $StriMia = $NomeVoce & Space(iDiff) & $StriMia
            AllineaCelleGrid = New AllinCelleGriBox(GriTabMovv, iTotRgGri, 2, $StriMia, "dx")
          Else
            AllineaCelleGrid = New AllinCelleGriBox(GriTabMovv, iTotRgGri, 2, $NomeVoce & " /// " & $StriMia, "dx")
          Endif


Per completezza riporto la classe "AllinCelleGRiBox":
Codice: gambas [Seleziona]
' Gambas class file

'------------------------------- AllinCelleGriBox.Class ------------------------------------------------------------------------------------------
' Questa Classe dinamica si occupa dell'allineamento del contenuito di una cella interna ad una GridBox: -----------------------------------------
' cx --> codice identificativo della richiesta di un allineamento centrale rispetto alla cella --------------------------------------------------
' dx --> codice identificativo della richiesta di un allineamento laterale destro rispetto alla cella -------------------------------------------
' ct --> codice identificativo della richiesta di un allineamento centrale della testata della GridBox --------------------------------------------------
'-------------------------------------------------------------------------------------------------------------------------------------------------
Private iLunCasel As Integer
Private iLunSpazio As Integer
Private iLunTesto As Integer
Private i_Risult As Integer

Public Sub _new(hObject As GridView, i_NumRg As Integer, i_NumCol As Integer, $_Testo As String, $_TipAllin As String)          'Funzione di allineamento destrorso del testo
'------------------------------------------------------- 
  ' [GB2:FNTW] i_LunSpazio = hObject.Font.Width(" ")
  iLunSpazio = hObject.Font.TextWidth(" ")
  ' [GB2:FNTW] i_LunTesto = hObject.Font.Width($_Testo)
  iLunTesto = hObject.Font.TextWidth($_Testo)
  iLunCasel = hObject.Columns[i_NumCol].Width
  i_Risult = (iLunCasel - iLunTesto) / iLunSpazio - 1
  Select Case $_TipAllin
          Case "sx"
            AllinSx(hObject, i_NumRg, i_NumCol, $_Testo)
          Case "dx"
            AllinDx(hObject, i_NumRg, i_NumCol, $_Testo)
          Case "cx"
            AllinCen(hObject, i_NumRg, i_NumCol, $_Testo)
          Case "ct"
            CenTestata(hObject, i_NumCol, $_Testo)
          Case "dt"
            AllinDxTestata(hObject, i_NumCol, $_Testo)
  End Select
End

Public Sub AllinDx(hObject As GridView, i_NumRg As Integer, i_NumCol As Integer, $_Testo As String)          'Funzione di allineamento destrorso del testo
'----------------------------------------------------------------
  If i_Risult > 0 Then
      hObject[i_NumRg, i_NumCol].text = String$(i_Risult, " ") & $_Testo
  Else
    hObject[i_NumRg, i_NumCol].text = $_Testo
  Endif
End

Public Sub AllinCen(hObject As GridView, i_NumRg As Integer, i_NumCol As Integer, $_Testo As String)          'Funzione di allineamento centrale del testo
'----------------------------------------------------------------
  If i_Risult > 0 Then
      i_Risult /= 2
      hObject[i_NumRg, i_NumCol].text = String$(i_Risult, " ") & $_Testo & String$(i_Risult, " ")
  Else
    hObject[i_NumRg, i_NumCol].text = $_Testo
  Endif
End

Public Sub AllinSx(hObject As GridView, i_NumRg As Integer, i_NumCol As Integer, $_Testo As String)          'Funzione di allineamento destrorso del testo
'----------------------------------------------------------------
  If i_Risult > 7 Then
      hObject[i_NumRg, i_NumCol].text = $_Testo & String$(i_Risult, " ")
'      hObject[i_NumRg, i_NumCol].text = $_Testo & String$(i_Risult - 7, " ")
  Else
    hObject[i_NumRg, i_NumCol].text = $_Testo
  Endif
End

Public Sub AllinDxTestata(hObject As GridView, i_NumCol As Integer, $_Testo As String)          'Funzione di allineamento destrorso della testata di colonna
  If i_Risult > 0 Then
      hObject.Columns[i_NumCol].text = String$(i_Risult, " ") & $_Testo
  Else
    hObject.Columns[i_NumCol].text = $_Testo
  Endif
End
Public Sub CenTestata(hObject As GridView, i_NumCol As Integer, $_Testo As String)          'Funzione di allineamento centrale della testata di colonna
'----------------------------------------------------------------------------------------------------------
  If i_Risult > 0 Then
      i_Risult /= 2
      hObject.Columns[i_NumCol].text = String$(i_Risult, " ") & $_Testo & String$(i_Risult, " ")
  Else
    hObject.Columns[i_NumCol].text = $_Testo
  Endif
End

La classe "AllinCelleGRiBox" completa la lunghezza della stringa con tanti caratteri "spazio" quanti ne servono per impegnare tutta la casella. Essa viene richiamata due volte, la prima per riempire tutta la casella con la prima variabile, la seconda, dopo avere riunito entrambi le variabili, la prima a sx, la seconda a dx, della stringa di transito. La logica funziona solo teoricamente, perchè applicata praticamente, purtroppo, la stringa finale oltrepassa l'ampiezza della cella di GridView destinataria.
A prima vista ho la sensazione che il problema sia sulle dimensioni e sul tipo di font in base al quale lavora la classe "AllinCelleGRiBox" che, credo, debba essere diverso da quello utilizzato poi per la casella di destinazione.

Se qualcuno non dovesse risolvere l'enigma prima di me, vi saprò dire. ;D
 :ciao:  :ciao:
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: vuott - 20 Novembre 2013, 01:42:33
A prima vista ho la sensazione che il problema sia sulle dimensioni e sul tipo di font in base al quale lavora la classe..


...se si potesse sapere  a priori :hard: da quanti caratteri può essere colmata la riga della GridView....


Titolo: Re: GridView con header, allineamento testo header?
Inserito da: vuott - 20 Novembre 2013, 02:29:49
...se si potesse sapere  a priori :hard: da quanti caratteri può essere colmata la riga della GridView....


Questo può essere conseguito con sufficiente accuratezza conoscendo la dimensione in pixel dei caratteri sulla base del font e delle altre loro caratteristiche assegnate.

Nell'esempio che segue abbiamo una GridView con tre colonne e tre righe. Nella prima riga della prima colonna vogliamo porre la parola "ali", tutta a sinistra, e la parola "baba" tutta a destra della riga.

In sintesi espongo di seguito la mia elaborazione:
Codice: gambas [Seleziona]

Public Sub Form_Open()

 Dim a, b, c, d As Short


  d = 140

  With GridView1
    .Columns.count = 3
    .Rows.Count = 3
' Dimensioniamo la lunghezza dell'intera prima colonna di 140 pixel:
    .Columns[0].Width = d
  End With


  With GridView1[0, 0]   ' Individuiamo la prima riga della prima colonna
' Impostiamo l'allineamento del testo al suo interno come "centrale":
    .Alignment = Align.Center
' Verifichiamo quanti pixel occupa il carattere di uno "spazio":
    a = .Font.TextWidth(String$(1, Chr(32)))
' Verifichiamo quanti pixel occupa l'intera parola "ali":
    b = .Font.TextWidth("ali")
' Verifichiamo quanti pixel occupa l'intera parola "baba":
    c = .Font.TextWidth("baba")

' Quindi applichiamo, con un po' di alchimia ed intrugli vari, l'elaborazione alla riga prescelta della GridView:
    .Text = "ali" & String$((d - (b + c)) \ a, Chr(32)) & "baba"
  End With

End




...sopravviverò all'ardua sentenza ?  :-X
Titolo: Re: GridView con header, allineamento testo header?
Inserito da: Picavbg - 20 Novembre 2013, 10:29:28
...se si potesse sapere  a priori :hard: da quanti caratteri può essere colmata la riga della GridView....

Non te la prendere vuott: l'ampiezza in pixel della casella incriminata la conosco benissimo, perchè la imposto io nella funzione di costruzione della GridView.  ;D
Però ..., nonostante che non ti abbia comunicato detta ampiezza, mi hai battuto nel tempo; complimenti!  ;D

Pertanto, avendo già nota l'ampiezza della casella da valorizzare, è stato tutto molto più semplice. Riporto la parte di programma così come l'ho modificata:
Codice: gambas [Seleziona]
 iLun = GriTabMovv[iTotRgGri, 2].Font.TextWidth(" ")       'calcola l'impegno in pixel del crt " "
          $StriMia = "Totali pregressi a riporto => SALDO: " & $Valuta & " " & EdtImp.$Imp
          iLunx = GriTabMovv[iTotRgGri, 2].Width                                       ' ampiezza della casella
          iLun1 = GriTabMovv[iTotRgGri, 2].Font.TextWidth($NomeVoce)     ' ampiezza della 1^ stringa
          iLun2 = GriTabMovv[iTotRgGri, 2].Font.TextWidth($StriMia)           ' ampiezza della  2^ stringa
          iDiff = iLunx - (iLun1 + iLun2)
          If iDiff > 0 Then
            $StriMia = $NomeVoce & Space$(iDiff \ iLun) & $StriMia            'Stringa che andrà a riempire la casella
            GriTabMovv[iTotRgGri, 2].Text = $StriMia
          Else
            GriTabMovv[iTotRgGri, 2].Text = $NomeVoce & " /// " & $StriMia     'Stringa che andrà a riempire la casella, nel caso eccezionale che non occorra aggiungere spazi intermedi
          Endif
          GriTabMovv[iTotRgGri, 2].Alignment = Align.Right

L'ho provata e funziona benissimo! D'altronde, dopo il tuo intervento, non poteva essere che così.  :D
Graziiiissime!
 :ciao: