PC Review


Reply
Thread Tools Rate Thread

Re: how-to autosize the width of a column in a DataGrid

 
 
Herfried K. Wagner [MVP]
Guest
Posts: n/a
 
      5th Sep 2003
"Mark Kamoski" <(E-Mail Removed)> schrieb:
> How can one autosize (that is-- size to fit the largest item) a column in

a
> DataGrid in a VB.NET desktop application?


http://www.syncfusion.com/faq/winforms/search/1004.asp

--
Herfried K. Wagner
MVP VB Classic, VB.NET
http://www.mvps.org/dotnet


 
Reply With Quote
 
 
 
 
Slonjo
Guest
Posts: n/a
 
      16th Sep 2003
I've placed an adapted version of this autosize code into an inherited
datagrid class .

I am noticing that when you call this autosize code multiple times,
you get 'phantom' columns that are duplicates of the originals. I
call them phantoms because when you check the locals window or the
code in debug mode, the grid thinks it only has the original number of
columns. Also, these additional columns are not 'autosized' as the
originals are.

Each time I call the autosize code, a new group of phantom columns is
added to the end of the grid???

Something to do with the CreateGraphics call I think.

Any ideas?

I've pasted my Grid class below.

================================================================================
Option Explicit On
Option Strict On
Public Class Grid
' every function in this library requires the grid
' to have a tablestyle and a datatable or dataview as it's
datasource.
' if no tablestyle is detected, one is automatically created.
'
' 20030911 DLD
Inherits Windows.Forms.DataGrid

Private m_strTableStyleRef As String = "0"

Sub New()
Me.New(False)
End Sub

Sub New(ByVal bolSetDefaultProperties As Boolean)
MyBase.New()
If bolSetDefaultProperties Then SetDefaultProperties()
End Sub

Public Property TableStyleRef() As String
Get
Return m_strTableStyleRef
End Get
Set(ByVal Value As String)
m_strTableStyleRef = Value
End Set
End Property

Private ReadOnly Property _ts() As Windows.Forms.DataGridTableStyle
Get
Dim lts As Windows.Forms.DataGridTableStyle
Try
If IsNumeric(TableStyleRef) Then
lts = Me.TableStyles(CInt(TableStyleRef))
Else
lts = Me.TableStyles(TableStyleRef)
End If

Catch exc As Exception
If lts Is Nothing Then
' if no tablestyle is assigned, create and add one...
lts = New Windows.Forms.DataGridTableStyle(True)
lts.MappingName = _dt.TableName
TableStyleRef = lts.MappingName
TableStyles.Add(lts)
CreateColumnMappings()
End If
Finally
'lts = Nothing
End Try
Return lts
End Get
End Property

Private ReadOnly Property _dt() As DataTable
Get
If TypeOf Me.DataSource Is DataTable Then
Return DirectCast(Me.DataSource, DataTable)
ElseIf TypeOf Me.DataSource Is DataView Then
Return DirectCast(Me.DataSource, DataView).Table
End If
End Get
End Property

Private ReadOnly Property _RowCount() As Integer
Get
If TypeOf Me.DataSource Is DataTable Then
Return DirectCast(Me.DataSource, DataTable).Rows.Count
ElseIf TypeOf Me.DataSource Is DataView Then
Return DirectCast(Me.DataSource, DataView).Count
End If
End Get
End Property

Public Sub SetDefaultProperties()
Try
With Me
.Hide()
.AllowSorting = True
.BorderStyle = Windows.Forms.BorderStyle.None
.CaptionText = String.Empty
.CaptionVisible = False
.ColumnHeadersVisible = True
'.DataSource = Nothing
.Enabled = True
'.FlatMode = True
.ForeColor = System.Drawing.Color.Navy
.GridLineStyle = Windows.Forms.DataGridLineStyle.Solid
'.GridLineColor=
'.ReadOnly = True
.RowHeadersVisible = True
'.TabStop = False
'.Visible = False
'.ResumeLayout()
.Visible = True
End With
Finally
End Try
End Sub

#Region "Save/Load Column Widths"

Function LoadSettings() As Boolean
Dim cs As Windows.Forms.DataGridColumnStyle
Try
Dim enu As IEnumerator = _ts.GridColumnStyles.GetEnumerator
While enu.MoveNext()
cs = CType(enu.Current, System.Windows.Forms.DataGridColumnStyle)
cs.Width = CInt(D.Registry.RegistryRead(Microsoft.Win32.RegistryHive.CurrentUser,
D.CommonLib.g_strAppRegPath & "Grids\" & Me.Name,
CStr(cs.MappingName)))
If cs.Width = 0 Then cs.Width = 70
End While
Return True
Catch exc As Exception
'D.ExceptionHandler.HandleExc(exc, False)
Finally
cs = Nothing
End Try
End Function

Function SaveSettings() As Boolean
Dim cs As Windows.Forms.DataGridColumnStyle
Try
Dim enu As IEnumerator = _ts.GridColumnStyles.GetEnumerator
While enu.MoveNext()
cs = CType(enu.Current, System.Windows.Forms.DataGridColumnStyle)
D.Registry.RegistryWrite(Microsoft.Win32.RegistryHive.CurrentUser,
D.CommonLib.g_strAppRegPath & "Grids\" & Me.Name,
CStr(cs.MappingName), cs.Width.ToString)
End While
Return True
Catch exc As Exception
'D.ExceptionHandler.HandleExc(exc, False)
Finally
cs = Nothing
End Try
End Function
#End Region

#Region "Autosize Columns"

Public Sub AutoSizeColumnsToHeaderText()
AutoSizeColumnsToHeaderText(False)
End Sub

Public Sub AutoSizeColumnsToHeaderText(ByVal bolLeaveZeroWidthColumns
As Boolean)
' a tablestyle must already be created.
Dim intMaxLength As Integer
Dim colStyle As Windows.Forms.DataGridColumnStyle
Dim g As System.Drawing.Graphics
Try
For Each colStyle In _ts.GridColumnStyles
' the MeasureString function returns
' the Width of the text in pixels
' taking the text's font into consideration.

' set colStyle.Width = to length of header text
If colStyle.Width = 0 And bolLeaveZeroWidthColumns Then
Else
intMaxLength = CInt(Me.CreateGraphics.MeasureString(colStyle.HeaderText.ToString,
Me.Font).Width) + 5
colStyle.Width = intMaxLength
End If
intMaxLength = 0
Next
Catch exc As Exception
D.ExceptionHandler.HandleExc(exc, True)
Finally
colStyle.Dispose()
End Try
End Sub

Public Sub AutoSizeColumns()
AutoSizeColumns(False)
End Sub

Public Sub AutoSizeColumns(ByVal bolLeaveZeroWidthColumns As Boolean)
Dim intColCounter As Integer = 0
Dim intCols As Integer

Try
intCols = _dt.Columns.Count
If intCols = 0 Then Exit Try
Do While (intColCounter < intCols)
If _ts.GridColumnStyles(intColCounter).Width = 0 And
bolLeaveZeroWidthColumns Then
Else
AutoSizeColumn(intColCounter)
End If
intColCounter += 1
Loop
Catch exc As Exception
Finally
End Try
End Sub

Public Sub AutoSizeColumns(ByVal intStartingCol As Integer, ByVal
intEndCol As Integer)
Dim intColCounter As Integer
Try
intColCounter = intStartingCol
Do While (intColCounter <= intEndCol)
AutoSizeColumn(intColCounter)
intColCounter += 1
Loop
Catch exc As Exception
Finally
End Try
End Sub

Public Sub AutoSizeColumn(ByVal intColIndex As Integer)
Dim sngWidth As Single = 0
'Dim intRows As Integer = 0
Dim intRowCounter As Integer = 0
Dim g As System.Drawing.Graphics
Dim sf As System.Drawing.StringFormat
Dim sizeColText As System.Drawing.SizeF
Dim chrSearchChar As Char = " "c
Dim sngCharCount As Single

Try
' if there aren't any rows,
' there isn't any text to measure.
' Fall through and use the header text
' to set the column width
If _RowCount > 0 Then
g = System.Drawing.Graphics.FromHwnd(Me.Handle)
sf = New System.Drawing.StringFormat(System.Drawing.StringFormat.GenericTypographic)
' loop all rows to find width of the largest value in the column
Do While (intRowCounter < _RowCount)
sizeColText = g.MeasureString(Me(intRowCounter,
intColIndex).ToString, Me.Font, 500, sf)
If (sizeColText.Width > sngWidth) Then
sngWidth = sizeColText.Width
' now we are looking for spaces
' the MeasureString call above seems to ignore spaces
' even though they take up length???
' here we calc the number of spaces in the string
' and add a bit to the width for each space found
sngCharCount = Me(intRowCounter,
intColIndex).ToString.Split(chrSearchChar).GetUpperBound(0)
sngWidth += (sngCharCount * 7)
End If
intRowCounter += 1
Loop
End If
' grab the length of the header text
Dim sizeHeaderText As System.Drawing.SizeF =
g.MeasureString(_ts.GridColumnStyles(intColIndex).HeaderText, Me.Font)
' if the header text is wider than any of the column's values...
' use it's width as the column width
' so that at least the header text is visible.
If sngWidth < sizeHeaderText.Width Then sngWidth =
CSng(sizeHeaderText.Width)
' finally, set the column width and add a bit for good measure (no
pun)
_ts.GridColumnStyles(intColIndex).Width = CInt(sngWidth) + 8
Catch exc As Exception
D.ExceptionHandler.HandleExc(exc)
Finally
g.Dispose()
g = Nothing
sf.Dispose()
sf = Nothing
sizeColText = Nothing
End Try

End Sub

Private Sub CreateColumnMappings()
Dim cs As Windows.Forms.DataGridColumnStyle
Dim col As DataColumn
Dim i As Integer = 0
Try
For Each col In _dt.Columns
Me.TableStyles(TableStyleRef).GridColumnStyles(i).MappingName =
col.ColumnName
i += 1
Next
Catch exc As Exception
D.ExceptionHandler.HandleExc(exc)
Finally
cs = Nothing
col = Nothing
End Try
End Sub

#End Region

'Public Sub AutoSizeColumn(ByVal intColIndex As Integer)
' Dim sngWidth As Single = 0
' Dim intRows As Integer = 0
' Dim g As System.Drawing.Graphics
' Dim sf As System.Drawing.StringFormat
' Dim sizeColText As System.Drawing.SizeF
' Dim intRowCounter As Integer = 0
' Dim ts As Windows.Forms.DataGridTableStyle
' Try
' ts = Me.TableStyles(0)
' Try
' intRows = dt.Rows.Count
' If intRows = 0 Then Exit Try
' 'If TypeOf Me.DataSource Is DataTable Then
' ' intRows = CType(Me.DataSource, DataTable).Rows.Count
' 'ElseIf TypeOf Me.DataSource Is DataView Then
' ' intRows = CType(Me.DataSource, DataView).Table.Rows.Count
' 'End If

' g = System.Drawing.Graphics.FromHwnd(Me.Handle)
' sf = New System.Drawing.StringFormat(System.Drawing.StringFormat.GenericTypographic)

' Do While (intRowCounter < intRows)
' sizeColText = g.MeasureString(Me(intRowCounter,
intColIndex).ToString, Me.Font, 500, sf)
' If (sizeColText.Width > sngWidth) Then
' sngWidth = sizeColText.Width
' End If
' intRowCounter += 1
' Loop
' ts.GridColumnStyles(intColIndex).Width = CInt(sngWidth) + 5
' Catch exc As Exception
' D.ExceptionHandler.HandleExc(exc)
' Finally
' g.Dispose()
' g = Nothing
' sf.Dispose()
' sf = Nothing
' sizeColText = Nothing
' End Try
' Catch ex As Exception
' Finally
' End Try
'End Sub
End Class
================================================================================
 
Reply With Quote
 
 
 
 
Slonjo
Guest
Posts: n/a
 
      16th Sep 2003
I also found that this happens after hitting my "autogenerate tablestyle" code.

More debugging required.

Nevermind.


(E-Mail Removed) (Slonjo) wrote in message news:<(E-Mail Removed)>...
> I've placed an adapted version of this autosize code into an inherited
> datagrid class .
>
> I am noticing that when you call this autosize code multiple times,
> you get 'phantom' columns that are duplicates of the originals.

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Textbox width scaling to width of data not width of page? AndrewF Microsoft ASP .NET 1 10th Oct 2005 05:38 PM
autosize DataGrid column Tim Wallace Microsoft C# .NET 2 18th Jul 2005 06:48 PM
Autosize datagrid column =?Utf-8?B?QWRuYW4=?= Microsoft Dot NET Compact Framework 0 15th Dec 2004 06:57 AM
Autosize the column width Jim Coyne Microsoft Excel Programming 5 21st May 2004 05:50 AM
Re: how-to autosize the width of a column in a DataGrid One Handed Man Microsoft VB .NET 0 5th Sep 2003 08:59 AM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 12:16 AM.