|
web
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Datagrid resizing rows on sort - not wantedI 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? 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 -------------------- "skOOb33" <skOO***@gmail.com> wrote in message I successfully autosized the columns and rows on my Datagrid, and amnews:1113316688.955195.223480@z14g2000cwz.googlegroups.com... 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? A couple questions. Can that class just inherit the
DataGridTextBoxColumn, or just the HotTrackTextBoxColumn? Also, there seems to be no function named MouseOverCell() given, but is used in the Paint method. Any clarification is appreciated. Thanks. Hi,
Sorry you can use datagridtextbox column instead of the hottracktextbox column and get rid of the line with mouseovercell. But here is Hottracktextboxcolumn in case you want it. It will highlight the cell the mouse is over. Imports System.Drawing Imports System.Drawing.Drawing2D Imports System.Windows.Forms Imports System.Reflection Imports System.ComponentModel Public Class HotTrackTextBoxColumn Inherits DataGridTextBoxColumn Dim c As Integer Dim rectPaint As New RectangleF Dim fnt As New Font(MyBase.TextBox.Font.Name, MyBase.TextBox.Font.Size, FontStyle.Underline) Dim WithEvents dg As DataGrid Dim oldCell As New Point(-1, -1) Dim isInCell As Boolean = False Public Sub HandleMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles dg.MouseMove Dim g As Graphics = dg.CreateGraphics Dim bounds As Rectangle Dim hti As DataGrid.HitTestInfo = dg.HitTest(New Point(e.X, e.Y)) isInCell = (hti.Row > -1 And hti.Column = c) Static bRedraw As Boolean = False If isInCell Then Dim pt As Point pt = New Point(hti.Row, hti.Column) If Not pt.Equals(oldCell) Then ' ' Create a region where we want the datagrid to redraw ' So the datagrid doesn't flash. ' Dim pthToRedraw As New Drawing2D.GraphicsPath Dim rgnToRedraw As Region Dim rCell As Rectangle = dg.GetCellBounds(pt.X, pt.Y) pthToRedraw.AddRectangle(rCell) If oldCell.X > -1 Then ' ' Have to redraw last cell ' pthToRedraw.AddRectangle(dg.GetCellBounds(oldCell.X, oldCell.Y)) End If rgnToRedraw = New Region(pthToRedraw) dg.Invalidate(rgnToRedraw) End If ' ' Flag datagrid for redraw ' bRedraw = True oldCell = pt Else ' ' Only redraw when needed ' If bRedraw Then dg.Invalidate(dg.GetCellBounds(oldCell.X, oldCell.Y)) End If bRedraw = False oldCell = New Point(-1, -1) End If 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 ' ' First time we paint get a reference to datagrid ' So we can consume its events ' If Not bPainted Then dg = Me.DataGridTableStyle.DataGrid c = -1 For Each grdCol As DataGridColumnStyle In Me.DataGridTableStyle.GridColumnStyles c += 1 If grdCol.MappingName = Me.MappingName Then Exit For Next End If bPainted = True MyBase.Paint(g, bounds, source, rowNum, backBrush, foreBrush, alignToRight) Dim pnHot As New Pen(SystemColors.HotTrack) Dim brHot As New SolidBrush(Color.FromArgb(128, SystemColors.HotTrack)) ' see through brush If MouseOverCell(rowNum) Then bounds.Inflate(-1, -1) g.FillRectangle(brHot, bounds) g.DrawRectangle(pnHot, bounds) End If Dim r As New RectangleF(bounds.X, bounds.Y, bounds.Width, bounds.Height) rectPaint = r End Sub Public ReadOnly Property MouseOverCell(ByVal rownum As Integer) As Boolean Get Dim pt As New Point(rownum, c) Return pt.Equals(oldCell) End Get End Property End Class Ken --------------------- "skOOb33" <skOO***@gmail.com> wrote in message A couple questions. Can that class just inherit thenews:1113325796.355308.317590@l41g2000cwc.googlegroups.com... DataGridTextBoxColumn, or just the HotTrackTextBoxColumn? Also, there seems to be no function named MouseOverCell() given, but is used in the Paint method. Any clarification is appreciated. Thanks. Thanks. All I did to rectify the issue was set a timer for 1/2 a
second to resize the rows after the sort. It isn't as good as I wanted because there is a slight flicker after you sort. I wasn't able to resize at the right time/event without the timer. I put your HotTrack to use, and it's a pretty cool feature. Probably won't fly with the "higher-ups" for now, but probably with one of my next projects. Thanks. If you have any ideas on a seemless autosizing after sorting, I would be interested. thx
complex grid with comboboxes
Reading from a ini-file and run a program Easy one about web forms How do I measure the time it takes to copy a file? checkbox in dataset step by step guide to databinding? Positioning a Web Control - Runtime Datagrid 's TextBox input format question. Registering my program as default for my file extension Inherited Treeview control with dynamic context menu. |
|||||||||||||||||||||||