About Me

My photo
Northglenn, Colorado, United States
I'm primarily a BI Developer on the Microsoft stack. I do sometimes touch upon other Microsoft stacks ( web development, application development, and sql server development).

Thursday, March 22, 2007

Setting a custom datagrid's row's height

I'm so glad to find this on the web. I needed to set the height of a double-clicked row to adjust the height. Normally the height is already adjusted in the default datagrid, but when you override it -- you lose this ability. Found this at http://vbcity.com/forums/faq.asp?fid=30&cat=Windows+Forms

<Description("Sets the height of one row.")> _

Public Sub SetRowHeight(ByVal Row As Integer, ByVal height As Integer)

Try

Dim d As New DataGrid()

Dim p As PropertyInfo = d.GetType.GetProperty("DataGridRows", BindingFlags.FlattenHierarchy Or BindingFlags.IgnoreCase Or BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public Or BindingFlags.Instance Or BindingFlags.Static)

Dim r As Object() = p.GetValue(Me, BindingFlags.Instance Or BindingFlags.Static Or BindingFlags.GetProperty Or BindingFlags.Public Or BindingFlags.SuppressChangeType, Nothing, Nothing, Nothing)

If Row < r.Length Then

r(Row).Height = height

Me.Invalidate()

Else

Throw New Exception("Row index outside of boundaries.")

End If

Catch

Throw New Exception("Error while reflecting. Framework version might be wrong.")

End Try

End Sub

Monday, March 12, 2007

VB.Net: Freeze a column in a data grid.

Ok, there is additional code that can be added to make this and feel more effiecient, but this gets the job done.

In your customize datagrid control override the horizontal scrollbar events with a class like this:

Protected Overrides Sub GridHScrolled(ByVal sender As Object, ByVal se As System.Windows.Forms.ScrollEventArgs)

Select Case se.Type

Case ScrollEventType.SmallIncrement, ScrollEventType.LargeIncrement
Dim SumWidth = 0
For i As Integer = _ColumnNumber + 1 To MyBase.TableStyles(0).GridColumnStyles.Count - 1
If MyBase.TableStyles(0).GridColumnStyles(i).Width > 0 Then
MyBase.TableStyles(0).GridColumnStyles(i).Width = 0
Exit For
End If
SumWidth += MyBase.TableStyles(0).GridColumnStyles(i).Width
Next
MyBase.TableStyles(0).GridColumnStyles(MyBase.TableStyles(0).GridColumnStyles.Count - 1).Width() += MyBase.TableStyles(0).DataGrid().Width - SumWidth

Case ScrollEventType.SmallDecrement, ScrollEventType.LargeDecrement
For i As Integer = MyBase.TableStyles(0).GridColumnStyles.Count - 1 To 1 Step -1
If MyBase.TableStyles(0).GridColumnStyles(i).Width = 0 Then
MyBase.TableStyles(0).GridColumnStyles(i).Width = 100
Exit For
End If
Next

Case ScrollEventType.EndScroll, ScrollEventType.First, ScrollEventType.Last, ScrollEventType.ThumbPosition, ScrollEventType.ThumbTrack
MyBase.GridHScrolled(sender, se)
End Select
Else
MyBase
.GridHScrolled(sender, se)
End If
End Sub

Thursday, March 01, 2007

Auto-Resize Columns in a data grid

So the data grids I've been working with are inherited from System.Windows.Forms.DataGrid. The problem I had was when a user double clicks between a column on the header to auto-fit the width of the column based on the data. Inside the inherited control you need something like:

Protected Overloads Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
If e.Button = MouseButtons.Left And e.Clicks > 1 And (Me.HitTest(e.X, e.Y).Type = DataGrid.HitTestType.ColumnResize) Then
Return 'Prevent sorting on the column if it's a resize
End If
End Sub




Then in the form's double click event I put something like:

Dim CursorPosition As System.Drawing.Point = dgr.PointToClient(Cursor.Position)
Dim DataGridHitTestInfo As DataGrid.HitTestInfo = dgr.HitTest(CursorPosition)

If DataGridHitTestInfo.Type = DataGrid.HitTestType.ColumnResize Or DataGridHitTestInfo.Type = DataGrid.HitTestType.ColumnHeader Then
Application.DoEvents()

Select Case DataGridHitTestInfo.Column
Case 2
Me.col2.Width() = ResizeColumn(Me.col2.MappingName, Me.col2.HeaderText)
Case 3
Me.col3.Width() = ResizeColumn(Me.col3.MappingName, Me.col3.HeaderText)
Case 4
Me.col4.Width() = ResizeColumn(Me.col4.MappingName, Me.col4.HeaderText)
Case 5
Me.col5.Width() = ResizeColumn(Me.col5.MappingName, Me.col5.HeaderText)
Case 6
Me.col6.Width() = ResizeColumn(Me.col6.MappingName, Me.col6.HeaderText)
End Select

Column_WidthChanged(sender, e)
End If



And added a function like this:


Private Function ResizeColumn(ByVal columnName As String, ByVal header As String) As System.String
Dim i As Integer
Dim length As Single = 0
Dim g As System.Drawing.Graphics = Me.dgr.CreateGraphics
Dim str As System.String
Dim strLength As Single
length = System.Math.Max(g.MeasureString(header, Me.Font).Width(), length)
For i = 0 To Me.dsPCDCodes.Tables(0).Rows.Count - 1
If Not IsDBNull(Me.ds.Tables(0).Rows(i).Item(columnName)) Then
str = CType(Me.ds.Tables(0).Rows(i).Item(columnName), System.String)
strLength = g.MeasureString(str, Me.Font).Width()
length = System.Math.Max(strLength, length)
End If
Next
Return length
End Function