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
> 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?") ?
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
Ciao, Io ci ho perso fior di giornate... Solo la cosa più bacata e che un
programmatore possa immaginare... di quei bachi subdoli...
> 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?") ?
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.
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.
--
-----------------------------------------------------------------
Bastianello Luciano - MBS CP Development
Software Consultant - Apprentice Sorcerer
MSN: cte...@hotmail.com - ICQ: 209754422
http://community.visual-basic.it/LucianoB/
-----------------------------------------------------------------
"Ettore Maronese (info htstone)" <ilmesT...@tiscalinet.it> ha scritto nel
messaggio news:dlfpsn$vjs$1...@domitilla.aioe.org...
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)
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.
Le ho usate per quello per cui mi servivano in quel momento.
Potresti, per favore, dettagliare meglio l'esempio che hai fatto?
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. :((
Non ricordo malfunzionamenti del genere. Ti succedeva con una colonna
"standard" o con una "ereditata"?
> - 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!
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
L'ho riscontrato su una mia ereditata e l'ho ricreato su quella "standard"..
ovvero, entrambe.
> > - 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!
>
> 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.
Non penso, penso piuttosto che con la giusta situazione capiterebbe anche
usando il BindingManagerBase.
Conta che accade anche con 2 finestre al posto del TabControl... una griglia
su una finestra e una sull'altra.
La MsgBox di errore che viene fuori è "incomprensibile", da debug il blocco
è nel codice di libreria che come origine (three calls) non ha il codice
scritto da me, ma la pompa di messaggi della finestra
(DispatchMessage/WindowProcedure) che richiama operazioni di aggiornamento
di un campo in binding, e dalla MsgBox non si capisce che il problema è dato
della griglia. Insomma.. Indebaggabile.
[CLIP]
> MyBindingManagerbase.SuspendBinding
> 'eliminare l'elemento dalla collection
> MyBindingManagerbase.ResumeBinding
Dovrebbero inventare una assicurazione sulle perdite di tempo provocate dai
bachi altrui.... :)
> Ciao, Io ci ho perso fior di giornate... Solo la cosa più bacata e che un
> programmatore possa immaginare... di quei bachi subdoli...
>
> ' 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!
ti ringrazio moltissimo sei stato davvero gentile
il commento non lo rimuovo e ti cito pure nell'about box, ci mancherebbe
altro!! :-)
grazie mille
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...)
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: