Hi,
When you sort the datagrid sets the row height back to the default
row height. They way I get around it is that I set the default row height
for all the rows to the biggest height and manually resize all the rows.
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
Imports System.Reflection
Imports System.ComponentModel
<DataSysDescription("This column style displays more than one line of
text")> _
Public Class MultiLineColumn
Inherits HotTrackTextBoxColumn
Private mTxtAlign As HorizontalAlignment
Private mDrawTxt As New StringFormat
Private mbAdjustHeight As Boolean = True
Private m_intPreEditHeight As Integer
Private m_rownum As Integer
Dim WithEvents dg As DataGrid
Private arHeights As ArrayList
Dim WithEvents cm As CurrencyManager
Dim mbTrack As Boolean = True
Public Property HotTrack() As Boolean
Get
Return mbTrack
End Get
Set(ByVal Value As Boolean)
mbTrack = Value
End Set
End Property
Private Sub GetHeightList()
Dim mi As MethodInfo = dg.GetType().GetMethod("get_DataGridRows",
BindingFlags.FlattenHierarchy Or BindingFlags.IgnoreCase Or
BindingFlags.Instance Or BindingFlags.NonPublic Or BindingFlags.Public Or
BindingFlags.Static)
Dim dgra As Array = CType(mi.Invoke(Me.dg, Nothing), Array)
arHeights = New ArrayList
Dim dgRowHeight As Object
For Each dgRowHeight In dgra
If dgRowHeight.ToString().EndsWith("DataGridRelationshipRow") = True Then
arHeights.Add(dgRowHeight)
End If
Next
End Sub
Public Sub New()
mTxtAlign = HorizontalAlignment.Left
mDrawTxt.Alignment = StringAlignment.Near
End Sub
Protected Overloads Overrides Sub Edit(ByVal source As
System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal bounds
As System.Drawing.Rectangle, ByVal [readOnly] As Boolean, ByVal instantText
As String, ByVal cellIsVisible As Boolean)
MyBase.Edit(source, rowNum, bounds, [readOnly], instantText, cellIsVisible)
Me.TextBox.TextAlign = mTxtAlign
Me.TextBox.Multiline = mbAdjustHeight
Debug.WriteLine(rowNum)
'If rowNum >= iRows Then
For x As Integer = 0 To arHeights.Count - 1
Dim pi As PropertyInfo = arHeights(x).GetType().GetProperty("Height")
Dim curHeight As Integer = CInt(pi.GetValue(arHeights(x), Nothing))
pi.SetValue(arHeights(x), curHeight, Nothing)
Next
Dim sz As Size = dg.Size
dg.Size = New Size(sz.Width - 1, sz.Height - 1)
dg.Size = sz
GetHeightList()
End Sub
Protected Overloads Overrides Sub Paint(ByVal g As System.Drawing.Graphics,
ByVal bounds As System.Drawing.Rectangle, ByVal source As
System.Windows.Forms.CurrencyManager, ByVal rowNum As Integer, ByVal
backBrush As System.Drawing.Brush, ByVal foreBrush As System.Drawing.Brush,
ByVal alignToRight As Boolean)
Static bPainted As Boolean = False
If Not bPainted Then
MyBase.Paint(g, bounds, source, rowNum, foreBrush, backBrush, alignToRight)
dg = Me.DataGridTableStyle.DataGrid
GetHeightList()
End If
cm = source
'clear the cell
g.FillRectangle(backBrush, bounds)
'draw the value
Dim s As String = Me.GetColumnValueAtRow([source], rowNum).ToString()
Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height)
r.Inflate(-2, -2)
' get the height column should be
Dim sDraw As SizeF = g.MeasureString(s, Me.TextBox.Font, Me.Width, mDrawTxt)
Dim h As Integer = CInt(sDraw.Height) + 15
If mbAdjustHeight Then
AdjustHeight(h)
End If
g.DrawString(s, MyBase.TextBox.Font, foreBrush, r, mDrawTxt)
bPainted = True
If mbTrack = True And Me.MouseOverCell(rowNum) Then
g.DrawRectangle(New Pen(SystemColors.HotTrack), r.Left, r.Top, r.Width,
r.Height)
End If
End Sub
<DataSysDescription("Automatically increase height of column")> _
Public Property AutoAdjustHeight() As Boolean
Get
Return mbAdjustHeight
End Get
Set(ByVal Value As Boolean)
mbAdjustHeight = Value
Try
dg.Invalidate()
Catch
End Try
End Set
End Property
Private Sub cm_PositionChanged(ByVal sender As Object, ByVal e As
System.EventArgs) Handles cm.PositionChanged
Static intOld As Integer = 0
If cm.Count > DirectCast(dg.DataSource, DataTable).Rows.Count Then
For x As Integer = 0 To arHeights.Count - 1
Dim pi As PropertyInfo = arHeights(x).GetType().GetProperty("Height")
Dim curHeight As Integer = CInt(pi.GetValue(arHeights(x), Nothing))
pi.SetValue(arHeights(x), curHeight, Nothing)
Next
Dim sz As Size = dg.Size
dg.Size = New Size(sz.Width - 1, sz.Height - 1)
dg.Size = sz
End If
intOld = cm.Position
End Sub
Private Sub AdjustHeight(ByVal h As Integer)
Dim curHeight As Integer = Me.DataGridTableStyle.PreferredRowHeight
If h > curHeight Then
'
' Manually set all the row heights to the new height
'
Me.DataGridTableStyle.PreferredRowHeight = h
Trace.WriteLine(h)
If arHeights.Count < cm.Count Then
GetHeightList()
End If
For rownum As Integer = 0 To cm.Count - 1
Try
Dim pi As PropertyInfo
pi = arHeights(rownum).GetType().GetProperty("Height")
' adjust height
If h > curHeight Then
pi.SetValue(arHeights(rownum), h, Nothing)
End If
Catch
' something wrong leave default height
Debug.WriteLine("Error")
End Try
Next
'
' Resize datagrid to get scrollbars to work right
'
Dim sz As Size = dg.Size
dg.Size = New Size(New Point(sz.Width - 1, sz.Height - 1))
dg.Size = sz
End If
End Sub
<DataSysDescription("Suspends painting of column until EndUpdate is
called")> _
Public Shadows Sub BeginUpdate()
MyBase.BeginUpdate()
End Sub
<DataSysDescription("Resumes painting of column")> _
Public Shadows Sub EndUpdate()
MyBase.EndUpdate()
End Sub
End Class
Ken
--------------------
I successfully autosized the columns and rows on my Datagrid, and am
now facing another issue. Having the sorting ability by clicking the
column headers is key, but when I do that, it resizes all my rows back
to their defaults. I populate the datagrid, resize it accordingly and
it works fine...just when I click the headers is when it messes up. It
would be fine if I could run my autosizing again after the sorting is
done since there won't be more than 50 rows usually, but I haven't been
able to figure that out.
I know when the user clicks on a column header, but when I run the
autosizing on the mouseup of that click, it just doesnt take. I see
the datagrid flicker with the right row heights, but it just always
goes right back to default. Any ideas on how to keep all the rows the
same size when a user clicks the column heading for sorting?