Xceed Grid for WinForms v4.3 Documentation
Building an unbound hierarchical master/detail grid

Welcome to Xceed Grid for WinForms v4.3 > Tutorials > Building an unbound hierarchical master/detail grid

This topic was designed to guide you through the steps required to build a typical unbound hierarchical master/detail grid. Each step will provide you with information on how to accomplish a specific task using both code and the Grid Designer to get you up and running efficiently.

Building an unbound grid

  1. Install Xceed Grid for WinForms and add it to your project. Don't forget to license the grid!
  2. Add the desired number of columns to the main grid specifying their FieldName and DataType. To change the text of the column as it appears in the column header, set the Title property.

    Because we will be doing batch modifications to the grid, the properties should be set between calls to the grid's BeginInit and EndInit methods. 

    See code

    VB.NET
    Copy Code
    Dim grid As New GridControl()
    
    grid.BeginInit() ' EndInit will be called later           
    
    ' Add the grid to the form
    
    Me.Controls.Add( grid )
    
    grid.Dock = DockStyle.Fill
    
    grid.Columns.Add( New Column( "FirstName", GetType( String ) ) )
    
    grid.Columns.Add( New Column( "LastName", GetType( String ) ) )
    
    grid.Columns.Add( New Column( "FamilyID", GetType( Integer ) ) )
    
    grid.Columns.Add( New Column( "Occupation", GetType( String ) ) )
    C#
    Copy Code
    GridControl grid = new GridControl();
    
    grid.BeginInit(); // EndInit will be called later           
    
    // Add the grid to the form
    
    this.Controls.Add( grid );
    
    grid.Dock = DockStyle.Fill;
    
    grid.Columns.Add( new Column( "FirstName", typeof( string ) ) );
    
    grid.Columns.Add( new Column( "LastName", typeof( string ) ) );
    
    grid.Columns.Add( new Column( "FamilyID", typeof( int ) ) );
    
    grid.Columns.Add( new Column( "Occupation", typeof( string ) ) );

     


Using the Grid Designer, columns can be added by right-clicking on grid and selecting the Add column (unbound) menu or using the verb in the property grid. By default, all the columns will be added with string data type. To change the column's data type and field name, select the column and change the value of the FieldName and DataType properties via the property grid. 

  1. You are now ready to populate the main grid with your data! To add rows, the grid's DataRows.AddNew method must be used. This method will return a DataRow whose content can be filled immediately or via the AddingDataRow event. This step can only be done via code.

    See code

    VB.NET
    Copy Code
    Dim row1 As Xceed.Grid.DataRow = grid.DataRows.AddNew()
    
    row1.Cells( "FirstName" ).Value = "Peter"
    
    row1.Cells( "LastName" ).Value = "Griffin"
    
    row1.Cells( "FamilyID" ).Value = 1
    
    row1.Cells( "Occupation" ).Value = "Fisherman"
    
    row1.EndEdit()
    
    Dim row2 As Xceed.Grid.DataRow = grid.DataRows.AddNew()
    
    row2.Cells( "FirstName" ).Value = "Homer"
    
    row2.Cells( "LastName" ).Value = "Simpson"
    
    row2.Cells( "FamilyID" ).Value = 2
    
    row2.Cells( "Occupation" ).Value = "Nuclear Technician"
    
    row2.EndEdit()
    C#
    Copy Code
    Xceed.Grid.DataRow row1 = grid.DataRows.AddNew();
    
    row1.Cells[ "FirstName" ].Value = "Peter";      
    
    row1.Cells[ "LastName" ].Value = "Griffin";
    
    row1.Cells[ "FamilyID" ].Value = 1;
    
    row1.Cells[ "Occupation" ].Value = "Fisherman";
    
    row1.EndEdit();
    
    Xceed.Grid.DataRow row2 = grid.DataRows.AddNew();
    
    row2.Cells[ "FirstName" ].Value = "Homer";
    
    row2.Cells[ "LastName" ].Value = "Simpson";
    
    row2.Cells[ "FamilyID" ].Value = 2;
    
    row2.Cells[ "Occupation" ].Value = "Nuclear Technician";
    
    row2.EndEdit();

  1. Add the desired rows to the main grid. For the purposes of this example, we will add a ColumnManagerRow in the grid's FixedHeaderRows section. When using the Grid Designer, rows can be added by right clicking on any element in the grid and selecting the Add row... or Insert row... menu. It is also possible to add rows using the verbs in the property grid.

    See code

    VB.NET
    Copy Code
    grid.FixedHeaderRows.Add( New ColumnManagerRow() )
    C#
    Copy Code
    grid.FixedHeaderRows.Add( new ColumnManagerRow() );

  1. Configure the detail grid that will be added to the grid's collection of DetailGridTemplates. Begin by adding the desired number of columns to the detail grid specifying their FieldName and DataType. To change the text of the column as it appears in the column header, set the Title property.

    Once the detail grid is initialized, add it to the grid's collection of DetailGridTemplates.


    By default, a detail grid created via code will not have a ColumnManagerRow. If one is desired, it can be added to the detail grid's HeaderRows (or FooterRows) section.

    When using the Grid Designer, detail grids can be added by right-clicking on the DataRowTemplate or the main grid's body and selecting the Add detail grid menu or by using the verb in the property grid. Columns can be added by right-clicking on the body of detail grid and selecting the Add column (unbound) menu or using the verb in the property grid. By default, all the columns will be added with string data type. To change the column's data type and field name, select the column and change the value of the FieldName and DataType properties via the property grid.

    See code

    VB.NET
    Copy Code
    Dim detail As New DetailGrid()
    
    detail.HeaderRows.Add( New ColumnManagerRow() )
    
    detail.Columns.Add( New Column( "FirstName", GetType( string ) ) )
    
    detail.Columns.Add( New Column( "Relationship", GetType( string ) ) )
    
    detail.Columns.Add( New Column( "FamilyID", GetType( integer ) ) )
    
    grid.DetailGridTemplates.Add( detail )
    C#
    Copy Code
    DetailGrid detail = new DetailGrid();
    
    detail.HeaderRows.Add( new ColumnManagerRow() );
    
    detail.Columns.Add( new Column( "FirstName", typeof( string ) ) );
    
    detail.Columns.Add( new Column( "Relationship", typeof( string ) ) );
    
    detail.Columns.Add( new Column( "FamilyID", typeof( int ) ) );
    
    grid.DetailGridTemplates.Add( detail );

  1. Subscribe to the main grid's InitializingDetailGrid event to populate the contents of the detail grids that are to be added to the main grid for each DataRow in the main grid.

    For the purposes of this example, the event handler that will handle the InitializingDetailGrid events that are raised by the main grid will be called "init_details".

    See code

    VB.NET
    Copy Code
    AddHandler grid.InitializingDetailGrid, AddressOf Me.init_details     
    
    ' Because we called BeginInit at the beginning of the process
    
    ' we must call EndInit otherwise none of our modifications
    
    ' will be applied to the grid.
    
    grid.EndInit()
    C#
    Copy Code
    grid.InitializingDetailGrid += new InitializingDetailGridEventHandler( this.init_details );     
    
    // Because we called BeginInit at the beginning of the process
    
    // we must call EndInit otherwise none of our modifications
    
    // will be applied to the grid.
    
    grid.EndInit();

In Visual Basic .NET, this step must be done via code (as demonstrated above).

  1. In the InitializingDetailGrid event handler, we will populate the detail grids of each DataRow according to the value of the parent DataRow's "FamilyID" cell.

    See code

    VB.NET
    Copy Code
    Private Sub init_details( ByVal sender As Object, ByVal e As InitializingDetailGridEventArgs )
    
      Select Case CType( e.Grid.ParentDataRow.Cells( "FamilyID" ).Value, Integer )
    
        Case 1
    
          Dim row1 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row1.Cells( "FirstName" ).Value = "Lois"
    
          row1.Cells( "Relationship" ).Value = "Wife"
    
          row1.Cells( "FamilyID" ).Value = 1
    
          row1.EndEdit()
    
          
    
          Dim row2 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row2.Cells( "FirstName" ).Value = "Meg"
    
          row2.Cells( "Relationship" ).Value = "Daughter"
    
          row2.Cells( "FamilyID" ).Value = 1
    
          row2.EndEdit()
    
     
    
          Dim row3 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row3.Cells( "FirstName" ).Value = "Chris"
    
          row3.Cells( "Relationship" ).Value = "Son"
    
          row3.Cells( "FamilyID" ).Value = 1
    
          row3.EndEdit()
    
     
    
          Dim row4 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row4.Cells( "FirstName" ).Value = "Stewie"
    
          row4.Cells( "Relationship" ).Value = "Son"
    
          row4.Cells( "FamilyID" ).Value = 1
    
          row4.EndEdit() 
    
     
    
          Dim row5 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row5.Cells( "FirstName" ).Value = "Brian"
    
          row5.Cells( "Relationship" ).Value = "Dog"
    
          row5.Cells( "FamilyID" ).Value = 1
    
          row5.EndEdit() 
    
        Case 2
    
          Dim row1 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row1.Cells( "FirstName" ).Value = "Marge"
    
          row1.Cells( "Relationship" ).Value = "Wife"
    
          row1.Cells( "FamilyID" ).Value = 2
    
          row1.EndEdit()
    
           
    
          Dim row2 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row2.Cells( "FirstName" ).Value = "Bart"
    
          row2.Cells( "Relationship" ).Value = "Son"
    
          row2.Cells( "FamilyID" ).Value = 2
    
          row2.EndEdit() 
    
     
    
          Dim row3 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row3.Cells( "FirstName" ).Value = "Lisa"
    
          row3.Cells( "Relationship" ).Value = "Daughter"
    
          row3.Cells( "FamilyID" ).Value = 2
    
          row3.EndEdit() 
    
     
    
          Dim row4 As Xceed.Grid.DataRow = e.Grid.DataRows.AddNew()
    
          row4.Cells( "FirstName" ).Value = "Maggie"
    
          row4.Cells( "Relationship" ).Value = "Daughter"
    
          row4.Cells( "FamilyID" ).Value = 2
    
          row4.EndEdit()
    
      End Select
    
    End Sub
    C#
    Copy Code
    private void init_details( object sender, InitializingDetailGridEventArgs e )
    
    {
    
      switch( ( int )e.Grid.ParentDataRow.Cells[ "FamilyID" ].Value )
    
      {
    
        case 1:
    
        {
    
          Xceed.Grid.DataRow row1 = e.Grid.DataRows.AddNew();
    
          row1.Cells[ "FirstName" ].Value = "Lois";
    
          row1.Cells[ "Relationship" ].Value = "Wife";
    
          row1.Cells[ "FamilyID" ].Value = 1;
    
          row1.EndEdit();       
    
          Xceed.Grid.DataRow row2 = e.Grid.DataRows.AddNew();
    
          row2.Cells[ "FirstName" ].Value = "Meg";
    
          row2.Cells[ "Relationship" ].Value = "Daughter";
    
          row2.Cells[ "FamilyID" ].Value = 1;
    
          row2.EndEdit(); 
    
          Xceed.Grid.DataRow row3 = e.Grid.DataRows.AddNew();
    
          row3.Cells[ "FirstName" ].Value = "Chris";
    
          row3.Cells[ "Relationship" ].Value = "Son";
    
          row3.Cells[ "FamilyID" ].Value = 1;
    
          row3.EndEdit();  
    
     
    
          Xceed.Grid.DataRow row4 = e.Grid.DataRows.AddNew();
    
          row4.Cells[ "FirstName" ].Value = "Stewie";
    
          row4.Cells[ "Relationship" ].Value = "Son";
    
          row4.Cells[ "FamilyID" ].Value = 1;
    
          row4.EndEdit();
    
          Xceed.Grid.DataRow row5 = e.Grid.DataRows.AddNew();
    
          row5.Cells[ "FirstName" ].Value = "Brian";
    
          row5.Cells[ "Relationship" ].Value = "Dog";
    
          row5.Cells[ "FamilyID" ].Value = 1;
    
          row5.EndEdit();  
    
      
    
          break;
    
        }
    
        case 2:
    
        {
    
          Xceed.Grid.DataRow row1 = e.Grid.DataRows.AddNew();
    
          row1.Cells[ "FirstName" ].Value = "Marge";
    
          row1.Cells[ "Relationship" ].Value = "Wife";
    
          row1.Cells[ "FamilyID" ].Value = 2;
    
          row1.EndEdit();        
    
     
    
          Xceed.Grid.DataRow row2 = e.Grid.DataRows.AddNew();
    
          row2.Cells[ "FirstName" ].Value = "Bart";
    
          row2.Cells[ "Relationship" ].Value = "Son";
    
          row2.Cells[ "FamilyID" ].Value = 2;
    
          row2.EndEdit(); 
    
          Xceed.Grid.DataRow row3 = e.Grid.DataRows.AddNew();
    
          row3.Cells[ "FirstName" ].Value = "Lisa";
    
          row3.Cells[ "Relationship" ].Value = "Daughter";
    
          row3.Cells[ "FamilyID" ].Value = 2;
    
          row3.EndEdit(); 
    
          Xceed.Grid.DataRow row4 = e.Grid.DataRows.AddNew();
    
          row4.Cells[ "FirstName" ].Value = "Maggie";
    
          row4.Cells[ "Relationship" ].Value = "Daughter";
    
          row4.Cells[ "FamilyID" ].Value = 2;
    
          row4.EndEdit();
    
          break;
    
        }
    
      }
    
    }

  2. Although this tutorial demonstrates how to add 1 detail grid per DataRow in the main grid, it is also possible to associate multiple detail grids to a DataRow and it is also possible to add detail grids to DataRows contained within detail grids. The number of DetailGrid objects added to the main grid's DetailGridTemplates collection indicates how many detail grids each DataRow in the main grid will have.

    If you want to add one or more detail grids to the DataRows contained within another detail grid, the same process is used: Configure a DetailGrid object that will be used a template to create the detail grids in the detail grid and add it to the detail grid's collection of DetailGridTemplates.

    Using the Grid Designer, right-click on the body or the DataRowTemplate of the parent detail grid  and select the Add detail grid menu or use the verb in the property grid. Once the detail grid is added to the parent detail grid, add the desired unbound columns using the Add column (unbound) menu or verb and then added the desired rows as demonstrated in the previous steps.

    In the following example,   we will use an unbound grid and allow the end-user to enter the data via an InsertionRow. Of course, this must be done before the main grid's EndInit method is called and before the parent detail grid is added to the main grid's collection of DetailGridTemplates otherwise a call to the main grid's (or the parent detail grid's) UpdateDetailGrids method must be made.

    See code

    VB.NET
    Copy Code
    Dim childDetail As New DetailGrid()
    
    childDetail.HeaderRows.Add( New InsertionRow() )
    
    childDetail.HeaderRows.Add( New ColumnManagerRow() )
    
    childDetail.Columns.Add( New Column( "Episode", GetType( string ) ) )
    
    childDetail.Columns.Add( New Column( "Date Aired", GetType( DateTime ) ) )
    
    detail.DetailGridTemplates.Add( childDetail )
    C#
    Copy Code
    DetailGrid childDetail = new DetailGrid();
    
    childDetail.HeaderRows.Add( new InsertionRow() );
    
    childDetail.HeaderRows.Add( new ColumnManagerRow() );
    
    childDetail.Columns.Add( new Column( "Episode", typeof( string ) ) );
    
    childDetail.Columns.Add( new Column( "Date Aired", typeof( DateTime ) ) );
    
    detail.DetailGridTemplates.Add( childDetail );