Articles in this section
Category / Section

How to efficiently customize the child table or group by using a custom engine in WinForms GridGroupingControl?

7 mins read

Customize the child table or group

When customizing the GridChildTable or GridGroup by deriving the GridChildTable in the custom engine, the OnInitializeVisibleCounters method and the OnEnsureInitialized method are to be overridden along with the other overrides. Otherwise the GridChildTable calls into the GridChildTable extend methods and sometimes bypasses methods like IsChildVisible, that you have overridden.

In the OnInitializeVisibleCounters override, the Total Visible Elements count, the Total Vertical Scroll Distance of elements in pixels, and the Total Custom Count of the visible elements must be calculated and set to the CachedVisibleCount, CachedYamountCount, and CachedVisibleCustomCount respectively. And the OnEnsureInitialized override method must return False, that is, when changes are detected and the object is not updated, to ensure that the object is up to date.

C#

public class GroupingEngineFactory : GridEngineFactoryBase
{
   // Add this line in your forms ctor:
   // GroupingEngineFactory provides a modified GridChildTable that adds an extra section.
   // GridEngineFactory.Factory = new GroupingEngineFactory();
   public override GridEngine CreateEngine()
   {
      return new GroupingEngine();
   }
}
public class GroupingEngine : GridEngine
{
   public override RecordRow CreateRecordRow(RecordRowsPart parent)
   {
      return new GroupingRecordRow(parent);
   }
   public override CaptionRow CreateCaptionRow(CaptionSection parent)
   {
      return new GroupingCaptionRow (parent);
   }
   public override ColumnHeaderRow CreateColumnHeaderRow(ColumnHeaderSection parent)
   {
      return new GroupingColumnHeaderRow (parent);
   }
}
public class GroupingRecordRow : GridRecordRow, IGridRowHeight
{
   int rowHeight = -1;
   /// Initializes a new object in the specifed record part.
   public GroupingRecordRow(RecordRowsPart parent) : base(parent)
   { }
   #region IGridRowHeight Members
   /// Determines if elements supports storing row heights
   public bool SupportsRowHeight()
   {
      return true;
   }
   public int RowHeight
   {
      get
      {
         return rowHeight;
      }
      set
      {
        if (rowHeight != value)
        {
          rowHeight = value;
          this.InvalidateCounterBottomUp();
        }
      }
   }
   // Checks if row height was modified or if default setting should be used.
   public bool HasRowHeight
   {
      get
      {
         return rowHeight != -1;
      }
   }
   #endregion
   /// <summary>
   /// This is where the row height then gets integrated with the engine.
   /// YAmount Counter logic.
   /// </summary>
   public override double GetYAmountCount()
   {
      // Note: whenever the value that is returned by GetYAmountCount changes, make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      return rowHeight != -1 ? rowHeight : base.GetYAmountCount();
   }
}
public class GroupingCaptionRow : GridCaptionRow, IGridRowHeight
{
   int rowHeight = -1;
   /// <summary>
   /// Initializes a new object in the specifed record part.
   /// </summary>
   /// <param name="parent">The parent element.</param>
   public GroupingCaptionRow(CaptionSection parent) : base(parent)
   { }
   #region IGridRowHeight Members
   /// <summary>
   /// Determines if elements supports storing row heights.
   /// </summary>
   /// <returns></returns>
   public bool SupportsRowHeight()
   {
      return true;
   }
   /// <summary>
   /// The row height.
   /// </summary>
   public int RowHeight
   {
      get
      {
         return rowHeight;
      }
      set
      {
         if (rowHeight != value)
         {
           rowHeight = value;
           this.InvalidateCounterBottomUp();
         }
      }
   }
   /// <summary>
   /// Checks if row height was modified or if default setting should be used.
   /// </summary>
   public bool HasRowHeight
   {
      get
      {
         return rowHeight != -1;
      }
   }
   #endregion
   /// <summary>
   /// This is where the row height then gets integrated with the engine.
   /// YAmount Counter logic.
   /// </summary>
   /// <returns></returns>
   public override double GetYAmountCount()
   {
      // Note: whenever the value that is returned by GetYAmountCount changes, make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      return rowHeight != -1 ? rowHeight : base.GetYAmountCount();
   }
   bool IGridRowHeight.HasRowHeight
   {
      get { throw new NotImplementedException(); }
   }
   int IGridRowHeight.RowHeight
   {
      get
      {
         throw new NotImplementedException();
      }
      set
      {
         throw new NotImplementedException();
      }
   }
   bool IGridRowHeight.SupportsRowHeight()
   {
      throw new NotImplementedException();
   }
}
public class GroupingColumnHeaderRow : GridColumnHeaderRow, IGridRowHeight
{
   int rowHeight = -1;
   /// <summary>
   /// Initializes a new object in the specifed record part.
   /// </summary>
   /// <param name="parent">The parent element.</param>
   public GroupingColumnHeaderRow(ColumnHeaderSection parent) : base(parent)
   { }
   #region IGridRowHeight Members
   /// <summary>
   /// Determines if elements supports storing row heights.
   /// </summary>
   /// <returns></returns>
   public bool SupportsRowHeight()
   {
      return true;
   }
   /// <summary>
   /// The row height.
   /// </summary>
   public int RowHeight
   {
      get
      {
         return rowHeight;
      }
      set
      {
         if (rowHeight != value)
         {
            rowHeight = value;
            this.InvalidateCounterBottomUp();
         }
      }
   }
   /// <summary>
   /// Checks if row height was modified or if default setting should be used.
   /// </summary>
   public bool HasRowHeight
   {
      get
      {
         return rowHeight != -1;
      }
   }
   #endregion
   /// <summary>
   /// This is where the row height then gets integrated with the engine.
   /// YAmount Counter logic.
   /// </summary>
   /// <returns></returns>
   public override double GetYAmountCount()
   {
      // Note: whenever the value that is returned by GetYAmountCount changes make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      return rowHeight != -1 ? rowHeight : base.GetYAmountCount();
   }
}

VB

Public Class GroupingEngineFactory
   Inherits GridEngineFactoryBase
   ' Add this line in your forms ctor:
   ' GroupingEngineFactory provides a modified GridChildTable that adds an extra section
   ' GridEngineFactory.Factory = new GroupingEngineFactory();
   Public Overrides Function CreateEngine() As GridEngine
      Return New GroupingEngine()
   End Function
End Class
Public Class GroupingEngine
   Inherits GridEngine
   Public Overrides Function CreateRecordRow(ByVal parent As RecordRowsPart) As RecordRow
      Return New GroupingRecordRow(parent)
   End Function
   Public Overrides Function CreateCaptionRow(ByVal parent As CaptionSection) As CaptionRow
      Return New GroupingCaptionRow (parent)
   End Function
   Public Overrides Function CreateColumnHeaderRow(ByVal parent As ColumnHeaderSection) As ColumnHeaderRow
      Return New GroupingColumnHeaderRow (parent)
   End Function
End Class
Public Class GroupingRecordRow
   Inherits GridRecordRow
   Implements IGridRowHeight
   Private rowHeight_Renamed As Integer = -1
   ''' Initializes a new object in the specifed record part.
   Public Sub New(ByVal parent As RecordRowsPart)
      MyBase.New(parent)
   End Sub
   #Region "IGridRowHeight Members"
   ''' Determines if elements supports storing row heights.
   Public Function SupportsRowHeight() As Boolean
      Return True
   End Function
   Public Property RowHeight() As Integer
      Get
         Return rowHeight_Renamed
      End Get
      Set(ByVal value As Integer)
        If rowHeight_Renamed <> value Then
          rowHeight_Renamed = value
          Me.InvalidateCounterBottomUp()
        End If
      End Set
   End Property
   ' Checks if row height was modified or if default setting should be used.
   Public ReadOnly Property HasRowHeight() As Boolean
      Get
         Return rowHeight_Renamed <> -1
      End Get
   End Property
   #End Region
   ''' <summary>
   ''' This is where the row height then gets integrated with the engine.
   ''' YAmount Counter logic.
   ''' </summary>
   Public Overrides Function GetYAmountCount() As Double
      ' Note: whenever the value that is returned by GetYAmountCount changes make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      Return If(rowHeight_Renamed <> -1, rowHeight_Renamed, MyBase.GetYAmountCount())
   End Function
End Class
Public Class GroupingCaptionRow
   Inherits GridCaptionRow
   Implements IGridRowHeight
   Private rowHeight_Renamed As Integer = -1
   ''' <summary>
   ''' Initializes a new object in the specifed record part.
   ''' </summary>
   ''' <param name="parent">The parent element.</param>
   Public Sub New(ByVal parent As CaptionSection)
      MyBase.New(parent)
   End Sub
   #Region "IGridRowHeight Members"
   ''' <summary>
   ''' Determines if elements supports storing row heights.
   ''' </summary>
   ''' <returns></returns>
   Public Function SupportsRowHeight() As Boolean
      Return True
   End Function
   ''' <summary>
   ''' The row height
   ''' </summary>
   Public Property RowHeight() As Integer
      Get
         Return rowHeight_Renamed
      End Get
      Set(ByVal value As Integer)
         If rowHeight_Renamed <> value Then
           rowHeight_Renamed = value
           Me.InvalidateCounterBottomUp()
         End If
      End Set
   End Property
   ''' <summary>
   ''' Checks if row height was modified or if default setting should be used.
   ''' </summary>
   Public ReadOnly Property HasRowHeight() As Boolean
      Get
         Return rowHeight_Renamed <> -1
      End Get
   End Property
   #End Region
   ''' <summary>
   ''' This is where the row height then gets integrated with the engine.
   ''' YAmount Counter logic.
   ''' </summary>
   ''' <returns></returns>
   Public Overrides Function GetYAmountCount() As Double
      ' Note: whenever the value that is returned by GetYAmountCount changes make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      Return If(rowHeight_Renamed <> -1, rowHeight_Renamed, MyBase.GetYAmountCount())
   End Function
   Private ReadOnly Property IGridRowHeight_HasRowHeight() As Boolean Implements IGridRowHeight.HasRowHeight
      Get
         Throw New NotImplementedException()
      End Get
   End Property
   Private Property IGridRowHeight_RowHeight() As Integer Implements IGridRowHeight.RowHeight
     Get
        Throw New NotImplementedException()
     End Get
     Set(ByVal value As Integer)
        Throw New NotImplementedException()
     End Set
   End Property
   Private Function IGridRowHeight_SupportsRowHeight() As Boolean Implements IGridRowHeight.SupportsRowHeight
     Throw New NotImplementedException()
   End Function
End Class
Public Class GroupingColumnHeaderRow
   Inherits GridColumnHeaderRow
   Implements IGridRowHeight
   Private rowHeight_Renamed As Integer = -1
   ''' <summary>
   ''' Initializes a new object in the specifed record part.
   ''' </summary>
   ''' <param name="parent">The parent element.</param>
   Public Sub New(ByVal parent As ColumnHeaderSection)
      MyBase.New(parent)
   End Sub
   #Region "IGridRowHeight Members"
   ''' <summary>
   ''' Determines if elements supports storing row heights.
   ''' </summary>
   ''' <returns></returns>
   Public Function SupportsRowHeight() As Boolean
      Return True
   End Function
   ''' <summary>
   ''' The row height
   ''' </summary>
   Public Property RowHeight() As Integer
      Get
         Return rowHeight_Renamed
      End Get
      Set(ByVal value As Integer)
        If rowHeight_Renamed <> value Then
          rowHeight_Renamed = value
          Me.InvalidateCounterBottomUp()
        End If
      End Set
   End Property
   ''' <summary>
   ''' Checks if row height was modified or if default setting should be used.
   ''' </summary>
   Public ReadOnly Property HasRowHeight() As Boolean
      Get
         Return rowHeight_Renamed <> -1
      End Get
   End Property
   #End Region
   ''' <summary>
   ''' This is where the row height then gets integrated with the engine.
   ''' YAmount Counter logic.
   ''' </summary>
   ''' <returns></returns>
   Public Overrides Function GetYAmountCount() As Double
      ' Note: whenever the value that is returned by GetYAmountCount changes make sure you call InvalidateCounterBottomUp so that the engine is aware of the change and counters are recalculated. See the RowHeight setter.
      Return If(rowHeight_Renamed <> -1, rowHeight_Renamed, MyBase.GetYAmountCount())
   End Function
End Class

Samples:

C#: Custom table

VB: Custom table

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied