Daily Archives: 07/14/2014

Infragistics WebDataGrid crashes if its total width over 32767 pixels

When you’re dealing with Infragistics WebDataGrid and want to manipulate appearance of individual columns – there’s a handy Columns collection for that. Unfortunately it’s available only if you define columns at design time or add columns to it in code-behind. If your grid features autogenerated columns – the collection will be empty.

There’s a way to derive column info tho – and can be done from grid row. The example below uses grid’s PreRender event to capture first row from which columns are derived and their width set:

Protected Sub xmyGrid_PreRender(sender As Object, e As EventArgs) Handles myGrid.PreRender
   Dim oGrid As GridControls.ContainerGrid
   Dim oRow As GridControls.ContainerGridRecord

   oGrid = sender
   oRow = oGrid.Rows(0)

   If oRow IsNot Nothing Then
      InitGridColumns(oRow) 'passing 1st grid row to helper sub
   End If
End Sub

Sub InitGridColumns(i_oRow As GridControls.ContainerGridRecord)
   Dim oGridCol As GridControls.BoundDataField

   'looping thru row cells
   For I As Integer = 0 To i_oRow.Items.Count - 1
       oGridCol = i_oRow.Items(I).Column 'deriving column object from row cell
       oGridCol.Width = Unit.Pixel(CalculateWidthHere()) 'setting calculated width
   Next
End Sub

This works pretty well – that is until summary width of all columns combined hit’s 32K. If this happens – grid crashes:

Continue reading →

WebHierarchicalDataGrid binds to data twice

Infragistics WebHierarchicalDataGrid offers a nice ability to custom load-on-demand data via its ContainerGridDataBinding event. It is very useful during paging or displaying grid children – you can make a DB call and provide data a just needed for current page or child.

But it has a drawback – if you need to programmaticaly sort the grid by manipulating SortedColumns collection – grid thinks it needs to rebind the data and is calling ContainerGridDataBinding event handler again thus making it execute DB call again – which is redundant and may hinder performance. In a typical scenario you have your binding code:

Protected Sub xmyGrid_ContainerGridDataBinding(sender As Object, e As GridControls.DataBindingEventArgs) Handles xmyGrid.ContainerGridDataBinding
   e.Cancel = True
   e.DataSource = MakeDbCallToGetCurrentData()
   e.SelectArguments.TotalRowCount = iTotalNumberOfRecords
End Sub

and somewhere else add sorting

Protected Sub xmyGrid_PreRender(sender As Object, e As EventArgs) Handles xmyGrid.PreRender
   xmyGrid.Behaviors.Sorting.SortedColumns.Add(sCol1Key, SortDirection.Ascending)
   xmyGrid.Behaviors.Sorting.SortedColumns.Add(sCol2Key, SortDirection.Descending)
End Sub

Sorting code in the second event handler is causing grid to perform second call to ContainerGridDataBinding. The solution is to move sorting code inside of ContainerGridDataBinding handler:

Protected Sub xmyGrid_ContainerGridDataBinding(sender As Object, e As GridControls.DataBindingEventArgs) Handles xmyGrid.ContainerGridDataBinding
   e.Cancel = True
   e.DataSource = MakeDbCallToGetCurrentData()
   e.SelectArguments.TotalRowCount = iTotalNumberOfRecords

   xmyGrid.Behaviors.Sorting.SortedColumns.Add(sCol1Key, SortDirection.Ascending)
   xmyGrid.Behaviors.Sorting.SortedColumns.Add(sCol2Key, SortDirection.Descending)
End Sub

Since at this point grid already bound to data – columns are already available. And since we’re inside of ContainerGridDataBinding – the call to it is not repeated.