Xceed Grid for WinForms v4.3 Documentation
How to create multiple column headers

Welcome to Xceed Grid for WinForms v4.3 > Task-Based Help > Appearance > How to create multiple column headers

The grid does support having more than one ColumnManagerRow in its headers, however it does not support (directly) having grouped column headers as demonstrated in the image below: 

In order to simulate column grouping you must create a custom row (that derives from the Row class and not from the ColumnManagerRow class) and use it in your grid.

Demonstration

The following code (class) demonstrates the minimum implementation required to simulate column grouping:

VB.NET Copy Code

Imports System
Imports Xceed.Grid
Imports System.Drawing
 
Public Class CustomColumnManagerRow
  Inherits Row
 
  Protected Sub New( ByVal template As CustomColumnManagerRow )
    MyBase.New( template )
  End Sub
 
  Public Sub New( ByVal selector As RowSelector )
    MyBase.New( selector )
  End Sub
    
  Public Sub New( ByVal columns As Integer )
    MyBase.New()
    m_columns = columns
  End Sub
    
  Protected Overrides Function CreateInstance() As Xceed.Grid.Row
    Return New CustomColumnManagerRow( Me )
  End Sub  
 
  Protected Overrides Sub PaintForeground( ByVal e As GridPaintEventArgs )
    Dim width As Integer = 0
    Dim lastColumn As Integer = 0
 
    Dim j As Integer
 
    For j = 0 To Me.ParentGrid.Columns.Count \ m_columns - 1
 
      Dim i As Integer
      For i = 0 To m_columns - 1
        width += Me.ParentGrid.Columns( lastColumn ).Width
        lastColumn = lastColumn + 1
      Next i  
                                
      e.Graphics.DrawLine( Me.ParentGrid.GridLinePen, e.DisplayRectangle.X + width - 1, _
                           0, e.DisplayRectangle.X + width - 1, Me.Height )
    Next j
  End Sub
 
  Protected Overrides ReadOnly Property DefaultHeight As Integer
    Get
      Return 16
    End Get
  End Property

  Protected Overrides Function GetFittedDisplayHeight( ByVal mode As AutoHeightMode, ByVal graphics As Graphics, ByVal printing As Boolean ) As Integer  
    Return Me.DefaultHeight
  End Function
 
  Protected Overrides Readonly Property DefaultCanBeCurrent As Boolean
    Get
      Return False
    End Get
  End Property
 
  Public Overrides ReadOnly Property IsBackColorAmbient As Boolean
    Get
      Return False
    End Get
  End Property
 
  Protected Overrides ReadOnly Property DefaultBackColor As System.Drawing.Color
    Get
      Return SystemColors.Control
    End Get
  End Property
 
  Private m_columns As Integer = 0
End Class

C# Copy Code

using System;
using Xceed.Grid;
using System.Drawing;
namespace Xceed.Grid
{
  public class CustomColumnManagerRow : Row
  {
    protected CustomColumnManagerRow( CustomColumnManagerRow template )
      :base( template ){}

    public CustomColumnManagerRow( RowSelector selector )
      :base( selector ){}   

    public CustomColumnManagerRow( int columns )
      :base()
    {
      m_columns = columns;
    }

    protected override Xceed.Grid.Row CreateInstance()
    {
      return new CustomColumnManagerRow( this );
    }

    protected override void PaintForeground( GridPaintEventArgs e )
    {
      int width = 0;
      int lastColumn = 0;
 
      for( int j = 0; j < this.ParentGrid.Columns.Count / m_columns; j++ )
      {
        for( int i = 0; i < m_columns; i++ )
        {
          width += this.ParentGrid.Columns[ lastColumn ].Width;        
          lastColumn++;
        }  
                                
        e.Graphics.DrawLine( this.ParentGrid.GridLinePen, e.DisplayRectangle.X + width - 1, 0,
                             e.DisplayRectangle.X + width - 1, this.Height );
      }
    }
 
    protected override int DefaultHeight
    {
      get{ return 16; }
    }

    protected override int GetFittedDisplayHeight( AutoHeightMode mode, Graphics graphics, bool printing )
    {
      return this.DefaultHeight;
    }
 
    protected override bool DefaultCanBeCurrent
    {
      get { return false; }
    }
 
    public override bool IsBackColorAmbient
    {
      get{ return false; }
    }
 
    protected override System.Drawing.Color DefaultBackColor
    {
      get{ return SystemColors.Control; }
    }
 
    private int m_columns = 0;    
  }
}

Your custom column manager row can then be used in your grid. For example:

VB.NET Copy Code

GridControl1.FixedHeaderRows.Insert( 0, _
                                     New CustomColumnManagerRow( gridControl1.Columns.Count / 2 ) )

GridControl1.FixedHeaderRows.Insert( 1, _
                                     New CustomColumnManagerRow( gridControl1.Columns.Count / 4 ) )

C# Copy Code

gridControl1.FixedHeaderRows.Insert( 0,
                                     new CustomColumnManagerRow( gridControl1.Columns.Count / 2 ) );

gridControl1.FixedHeaderRows.Insert( 1,
                                     new CustomColumnManagerRow( gridControl1.Columns.Count / 4 ) );

If you have a regular ColumnMangerRow in your grid, you must disable column reordering when also using this custom column manager row.

VB.NET Copy Code
ColumnManagerRow1.AllowColumnReorder = False
C# Copy Code
columnManagerRow1.AllowColumnReorder = false;