Newsgroup: it.comp.lang.visual-basic
Titolo: [.net] la larghezza delle colonne di un datagrid (sottotitolo: mi sembra di essere scemo)

salve gente
allora
puntuale come la stagione delle piogge, torno a chiedere lumi sui
famigerati datagrid di 
vb.net
c'era una volta un datagrid, che a runtime veniva collegato a un dataset a
sua volta riempito da un dataadapter. e tutto funzionava bene. finché al
sottoscritto non fu fatto notare che la dimensione delle colonne era sempre
uguale, e cio' non andava bene.
ora, mi chiedo: tenendo presente che sicuramente tutto è più bello di come
era una volta (sic), e che un semplice table.columns(i).width o simile è
sicuramente demodé e non abbastanza "pulito", mi chiedo: ma come strac@@@o
si fa a dire a vb "la colonna uno deve essere larga tot, la due tot e la
tre tot" (o magari, ma chissà se chiedo troppo, "caro 
vb.net
, mi
ridimensioni tu le colonne a seconda di quello che c'è dentro?") ?
:-)
grazie in anticipo
	d.
-- 
La bella che guarda il fiume ha un nome che fa paura...
La bella che è addormentata ha un nome che fa paura:
Libertà! Libertà! Libertà!
http://www.pilardeimeli.net

 ridimensioni tu le colonne a seconda di quello che c'è dentro?") ?
Prova a gestire e definire il datagridtablestyle, con un
datagridtextboxcolumn per ogni colonna che puoi dimensionare a piacere.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 ridimensioni tu le colonne a seconda di quello che c'è dentro?") ?
MA SEI PAZZO? pretendi che una griglia si aggiusti da sola? Ma è una follia!
Ma non se mai visto! Piuttosto, da codice fai .width di ogni campo. e' così
che bisogna fare... per buttare via tempo e salute... andando a cercare un
modo per farlo in modo più intelligente, ovvio dici tu... ma non scherziamo,
quelli della microfof sanno quello che fanno..... . .
Scherzi a parte, quelle griglie del ca**o non hanno nulla per addattarsi.. o
meglio io ho fatto la stessa fine tua, non l'ho trovato!!!!
Per quanto mi riguarda DISPERATO ho fatto una funzione che calcola in
automatico le dimensioni delle colonne della griglia in funzione del
DataTable assegnato.
Te la *Regalo* (ve la regalo) ma non fatemi notare che sto distribuendo
knowhow perchè sennò mi picchio da solo!!!!!
Questa la ritengo una chicca.
        Call WindowsForm.Funzioni.DimensionaCampiGriglia(grdArticoli,
grdArticoli.TableStyles(0), 500)
        Public Function DimensionaCampiGriglia(ByVal grd As DataGrid, ByVal
grdStile As DataGridTableStyle, ByVal NrEsami As Int32) As Int32
            '
            ' BY ETTORE MARONESE, il Mes
            ' H.T. Stone S.r.l.  
www.htstone.it
            ' 16/11/2005, NON Rimuovere questo commento, ti chiedo solo
questo!
            '
            Dim Tabella As DataTable
            Dim ixCol As Int32
            Dim grdCOL As DataGridColumnStyle
            Dim flgUsaCampo As Boolean
            Dim DimCols(150) As Int32
            Dim Grafica As System.Drawing.Graphics
            Dim CountRows As Int32
            Dim ixRow As Int32
            Dim Valore As String
            Dim tmpDim As Int32
            Dim MeWidth As Int32
            Try
                Grafica = grd.CreateGraphics()
                If TypeOf grd.DataSource Is DataTable Then
                    Tabella = grd.DataSource
                ElseIf TypeOf grd.DataSource Is DataView Then
                    Tabella = DirectCast(grd.DataSource, DataView).Table
                End If
                ' Inizializzo il vettore con le larghezze dei nomi delle
colonne
                For ixCol = 0 To grdStile.GridColumnStyles.Count - 1
                    If grdStile.GridColumnStyles.Item(ixCol).Alignment =
HorizontalAlignment.Right Then
                        If
grdStile.GridColumnStyles.Item(ixCol).HeaderText.EndsWith(" .") = False Then
                            grdStile.GridColumnStyles.Item(ixCol).HeaderText
+= " ." ' Per gli allineati a destra, aggiungo uno spazio! perchè sennò è
attaccato al bordo!
                        End If
                    End If
                    DimCols(ixCol) =
Grafica.MeasureString(grdStile.GridColumnStyles.Item(ixCol).HeaderText,
grd.HeaderFont).Width + 20
                Next ixCol
                ' Adatto il vettore con l'analisi a campione dei record
                For CountRows = 0 To NrEsami - 1
                    ixRow = (Tabella.Rows.Count / NrEsami) * CountRows
                    If ixRow >= Tabella.Rows.Count Then ixRow =
Tabella.Rows.Count - 1
                    If ixRow < 0 Then Exit For
                    If Tabella.Rows.Item(ixRow).RowState <>
DataRowState.Deleted Then
                        For ixCol = 0 To grdStile.GridColumnStyles.Count - 1
                            Dim Format As String
                            If TypeOf grdStile.GridColumnStyles(ixCol) Is
DataGridTextBoxColumn Then
                                Format =
DirectCast(grdStile.GridColumnStyles(ixCol), DataGridTextBoxColumn).Format
                            Else
                                Format = String.Empty
                            End If
                            If Format.Length Then
                                Valore = String.Format("{0:" & Format & "}",
Tabella.Rows.Item(ixRow).Item(grdStile.GridColumnStyles.Item(ixCol).MappingN
ame))
                            Else
                                Valore = String.Format("{0}",
Tabella.Rows.Item(ixRow).Item(grdStile.GridColumnStyles.Item(ixCol).MappingN
ame))
                            End If
                            tmpDim = Grafica.MeasureString(Valore,
grd.Font).Width + 16
                            If TypeOf grdStile.GridColumnStyles.Item(ixCol)
Is DataGridTextButtonColumn Then
                                tmpDim = tmpDim +
DirectCast(grdStile.GridColumnStyles.Item(ixCol),
DataGridTextButtonColumn).Button_Width + 3  ' +3 per dargli un po di spazio
:)
                            End If
                            If TypeOf grdStile.GridColumnStyles(ixCol) Is
DataGridLabelButtonColumn Then
                                tmpDim +=
DirectCast(grdStile.GridColumnStyles(ixCol),
DataGridLabelButtonColumn).Button_Width
                            End If
                            If DimCols(ixCol) < tmpDim Then DimCols(ixCol) =
tmpDim
                            If DimCols(ixCol) > 400 Then DimCols(ixCol) =
400
                        Next ixCol
                    End If
                Next CountRows
                ' Imposto la dimensione dei campi
                For ixCol = 0 To grdStile.GridColumnStyles.Count - 1
                    MeWidth = MeWidth + DimCols(ixCol)
                    grdStile.GridColumnStyles.Item(ixCol).Width =
DimCols(ixCol)
                Next ixCol
            Catch ex As Exception
                PrgLog.AddLogERRORE("Errore nella ridimensione dei campi
della griglia  '" & grd.Name & "'  (chiamante: " & New
System.Diagnostics.StackTrace(True).GetFrame(1).ToString & ")" & vbCrLf &
vbCrLf & ex.Message, "HTWindowsForm", HTLogFlg.flgDebug Or
HTLogFlg.flgMsgBox)
            End Try
            ' Torno la dimensione X che dovrebbe avere la finestra per
visualizzare tutti i campi
            Return MeWidth
        End Function
Poi la invierò al Sito Comune di queto NG!
CIAO
Ettore Maronese, il Mes
http://www.it-lang-vb.net
   << Il Migliore
Evitate di applicare il rasoio di Occam: "Pluralitas non est ponenda sine
necessitate", perchè significa rifugiarsi nella pigrizia.

 datagridtextboxcolumn per ogni colonna che puoi dimensionare a piacere.
E' quel "puoi dimensionare a piacere" il problema, perchè per dargli una
dimensione corretta devi lancire il programma, vedere se le dimensioni vanno
bene, chiudere, correggerle, rilanciarlo.. almeno 4..5 volte. Poi vai dal
cliente e ti accorgi che è ancora troppo stretto perchè scrive tutto in
maiuscolo...
Ma sta benedetta griglia non è capace di decidere lei una dimensione
intelligente?
Il codice che ho proposto nell'altra mail risolve questo problema... spero
:)
Ciao
Ettore Maronese, il Mes
http://www.it-lang-vb.net
   << Er +
Evitate di applicare il rasoio di Occam: "Pluralitas non est ponenda sine
necessitate", perchè significa rifugiarsi nella pigrizia senza cercare di
migliorarsi.

 ha scritto nel 
messaggio news:dlfpsn$vjs$1...@domitilla.aioe.org...


 programmatore possa immaginare... di quei bachi subdoli...
Non sono daccordo. Con la DataGrid, e soprattutto ereditando dagli oggetti
"colonna", riesci ad avere un controllo pressochè totale del funzionamento
della griglia.
-- 
Salutoni
Sergio
Per rispondere... togli il group dall'indirizzo
Se i tempi non chiedono la tua parte migliore, inventa altri tempi. 
(Baolian, libro II, vv. 16-17)


 della griglia.
L'ho fatto! Ed è per questo che ti dico che è bacata nel profondo! Per
esempio, In talune situazioni, con un camposelezionato ma non visualizzato
(è stato fatto uno scroll orrizzontale ed il campo non è visibile) se si
cambia di record la griglia si dimentica di informare le colonne che c'e'
stato un cambio di record. E altri ancora.
Se non ti hanno mai dato problemi, mi vien da dedurre che non le hai usate
in modo intensivo.


 in modo intensivo.
Le ho usate per quello per cui mi servivano in quel momento.
Potresti, per favore, dettagliare meglio l'esempio che hai fatto?


 
http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c44c.aspx#q877q
Ottimo esempio.
I codici hanno due differenze sostanziali, il mio valuta anche la dimensione
dei titoli dei campi e fa un controllo a campione (con nr di campionamenti
parametrizzato) dei record per evitare di andare a valutare decine di
migliaia di campi sprecando tempo di elaborazione per dimensionare una
griglia.
Se per esempio la griglia (tabella) ha 8000 record e 15 campi, verrebbero
già fatti 120'000 cicli/test.....



Quello del refresh è un casino dettagliarlo... è una combinazione di click
che vatti a ricordare com'è. Quello che succede è che la TextBox della
casella che era in edit, rimane a video quando sarebbe dovuta sparire visto
che la casella col fuoco è diventata un'altra.
Posso dettagliarti un'altro baco che mi ha fatto letteralmente impazzire.
Se hai una griglia e la devi ripopolare con un nuovo DataTable, in teoria
basterebbe un:
       grdgriglia.DataSource = TableInput
Hamè non è così.. o meglio, c'e' una condizione che così facendo va in
crash.
- Crea un form con dentro un TabControl, con 2 Tabpage (Tab1 e Tab2).
- Nella Tab1 ci metti una griglia popolata con un DataTable (es:
grdgriglia.DataSource = TableInput )
- Clicchi la Tab1, dai il fuoco alla Griglia, quindi clicchi sulla Tab2
- Aggiorni il Binding della griglia assegnandogli un nuovo DataTable (es:
grdgriglia.DataSource = TableInputNuovo )
- clicchi sulla Tab1... CRASH... la griglia va in errore!
Non ti dico quanti tentativi ho fatto ricavare un Work Around.
Alla fine il Work Around usato è questo:
        ' Per risolvere il baco della griglia
        grdGriglia.SetDataBinding(Nothing, "")
        If grdGriglia.ContainsFocus() Then Me.ActiveControl = Nothing
        grdGriglia.SetDataBinding(TableInputNuovo, "")
tre righe frutto di ore di testate contro il muro. :((


 - clicchi sulla Tab1... CRASH... la griglia va in errore!
Ho fatto (almeno) una applicazione che ha una datagrid contenuta in in un
tabcontrol, e modifico al runtime la sua fonte dati, ma non ricordo di
aver riscontrato particolari problemi. Ma la situazione è leggermente
diversa, perchè passo attraverso un BindingManagerBase, e può darsi che
questo modifichi sostanzialmente il funzionamento.
Piuttosto, ho parecchio battuto la testa con un listbox, che aveva come
fonte dati una collection: eliminare l'elemento in fondo alla lista, se
non era l'unico, provocava un simpatico errore di run time. Dopo svariate
ore di tentativi, la soluzione è stata:
MyBindingManagerbase.SuspendBinding
'eliminare l'elemento dalla collection
MyBindingManagerbase.ResumeBinding


 MyBindingManagerbase.ResumeBinding
Dovrebbero inventare una assicurazione sulle perdite di tempo provocate dai
bachi altrui.... :)


 ' 16/11/2005, NON Rimuovere questo commento, ti chiedo solo questo!
ti ringrazio moltissimo sei stato davvero gentile
il commento non lo rimuovo e ti cito pure nell'about box, ci mancherebbe
altro!! :-)
grazie mille


ridimensioni tu le colonne a seconda di quello che c'è dentro?") ?
Se non sono in ritardo
(premetto che non sono andato in profondità
con le due soluzioni che ti hanno proposto),
ma l'idea di popolare contemporaneamente alla cella 
anche una LABEL nascosta
con Autosize su True (e ovviamente con lo stesso Font della Grid)
ed appena popolata tale LABEL 
andare a leggergli la Width 
e con questo valore ricavato (quello che sarà il più largo di tutti)
andare a regolare la colonna della Grid 
è un metodo che risulta lento?
Se qualcuno lo ha provato o lo vuole provare
credo sarebbe interessante aver un riscontro.
(io per grandi quantità di righe non l'ho mai provato...)

crei un tablestyle da associare al datagrid
per ogni colonna crei un datagridcolumnstyle
per ogni datagridcolumnstyle metti i parametri che vuoi tra cui la
larghezza ed infine aggiungi le colonne al tablestyle e il tablestyle al
datagrid
puoi anche realizzarlo attraverso le propietà del datagrid
all'incirca dovrebbe essere cosi
Dim ts as TableStyle = new ...
dim c1 as DataGridColumnStyle = new ...
dim c2 as DataGridColumnStyle = new ...
c1.width = 12
c2.BackColor = 13
ts.DataGridColumnStyles.Add(c1)
ts.DataGridColumnStyles.Add(c2)
datagrid1.TableStyle.Add(ts)
Per richiamarlo runtime basta fare
DataGrid1.TableStyle(0).DataGridColumnStyles(0).width = ...
Il codice probabilmente non funzionerà ma non ho VS sotto mano.
In bocca al lupo
Dan Marino ha scritto:
