FlexGrid for WinForms | ComponentOne
Row / Row Detail
In This Topic
    Row Detail
    In This Topic

    Row detail is a feature to provide additional information related to a row or record in the form of another expandable layer. In such case, row which is the first layer contains the basic information, while the second layer contains the detailed information. This feature is specially useful when the additional information is too large to be displayed in the available screen space or it is not consistent for every record.

    Row detail

    FlexGrid provides the row detail feature using IC1FlexGridRowDetail interface which is implemented by the detail controls to be hosted on detail row. In addition, FlexGrid also provides a separate assembly C1.Win.C1FlexGrid.RowDetails to provide template user controls, InputPanel and FlexGrid, ready to be used in detail row. You can add details section to any row in FlexGrid, which enables you to group data in a template which is visible optionally. This allows users to view additional data related to a row by simply selecting the row. The grid also provides built-in expand or collapse buttons to control the visibility of data within the expandable row.

    Some common use case scenarios of row detail feature are:

    1. In-form editing where an InputPanel control is hosted to get input from the user to fill information in a record.
    2. Hierarchical grid which contains a master grid and a detail grid to show additional information about the record.
    3. Custom row details where any control can be used to create row detail template.

    Detailed implementation of these scenarios is given in their respective sections below.

    In-form Editing

    FlexGrid supports in-form editing by hosting InputPanel control in detail row. The InputPanel control contains data fields where user can enter or edit the values like a form. Once user finishes editing fields, those values get reflected in the selected row. 

    In-form Editing

    In FlexGrid, you can implement in-form editing by adding reference to C1.Win.C1FlexGrid.RowDetails and using the C1InputPanelRowDetail class which already implements the IC1FlexGridRowDetail interface. The instance of this class is then assigned to RowDetailProvider property of the C1FlexGrid class which adds the InputPanel control to detail row and enables the in-form editing.

    flexGrid.RowDetailProvider = (g, r) => new C1InputPanelRowDetail();
    flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected;        
    
    flexGrid.RowDetailProvider = Function(g, r) New C1InputPanelRowDetail()
    flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected
    
    Tip: C1InputPanelRowDetail is a UserControl with C1InputPanel inside and it provides mechanisms for extending its behavior - like Setup method which can be overrided with custom logic.

    Hierarchical View

    Hierarchical view refers to master-detail model where top level grid is the 'master grid' and nested grid is the 'detail grid' which displays additional information about expanded row of the master grid. For instance, example below demonstrates the master-detail structure using Customer and Order tables respectively with CustomerID as common data element to define a relation.

    Hierarchical View

    In FlexGrid, you can implement hierarchical grid by adding reference to C1.Win.C1FlexGrid.RowDetails.4.5.2.dll and using the C1FlexGridRowDetail class which already implements the IC1FlexGridRowDetail interface. The instance of this class is then assigned to RowDetailProvider property of the C1FlexGrid class to nest another grid in the detail row which enables the hierarchical grid interface.

     private void FlexGrid_Load(object sender, EventArgs e)
            {
                string conn = Util.GetConnectionString();
                var ds = new DataSet();
                string[] tables = "Customers, Orders".Split(',');
                foreach (string tableName in tables)
                {
                    Util.FillTable(ds, tableName, conn);
                }
              
             // Defining relation between master and detail grid
                ds.Relations.Add("Customers_Orders",
                    ds.Tables["Customers"].Columns["CustomerID"],
                    ds.Tables["Orders"].Columns["CustomerID"]);
                flexGrid.DataSource = ds;
                flexGrid.DataMember = "Customers";
                flexGrid.RowDetailProvider = (g, r) => new C1FlexGridRowDetail();
                flexGrid.AreRowDetailsFrozen = false;
            }
        }       
    
    Private Sub FlexGrid_Load(ByVal sender As Object, ByVal e As EventArgs)
          Dim conn As String = Util.GetConnectionString()
          Dim ds = New DataSet()
          Dim tables As String() = "Customers, Orders".Split(","c)
    
          For Each tableName As String In tables
              Util.FillTable(ds, tableName, conn)
          Next
          'Defining relation between master and detail grid
          ds.Relations.Add("Customers_Orders", ds.Tables("Customers").Columns("CustomerID"), ds.Tables("Orders").Columns("CustomerID"))
          flexGrid.DataSource = ds
          flexGrid.DataMember = "Customers"
          flexGrid.RowDetailProvider = Function(g, r) New C1FlexGridRowDetail()
          flexGrid.AreRowDetailsFrozen = False
     End Sub
    

    Custom Row Details

    In addition to the InputPanel and FlexGrid control, you can also host a custom control in the detail row of a grid. For instance, in the example below, a text label control is attached to the row to enlist the additional information without affecting the dimensions of the grid.

    Custom Row Details

    To implement the custom row details in FlexGrid, you need to create a user control which implements the IC1FlexGridRowDetail interface. For instance, here we have created a class named CustomRowDetail which represents the text label control to be hosted in the detail row. You then need to assign an object of this class to RowDetailProvider property of the C1FlexGrid class to enable the custom control to display additional information in the detail row.

      private void CustomSample_Load(object sender, EventArgs e)
      {
         flexGrid.DataSource = DemoDataSource("Employees");
         flexGrid.RowDetailProvider = (g, r) => new CustomRowDetail();
         flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected;
         flexGrid.Cols["Notes"].Visible = false;
      }
    
       // Custom row detail class which shows label with notes about employee       
       public class CustomRowDetail : C1Label, IC1FlexGridRowDetail
        {
            
          // Used to setup control before showing the FlexGrid detail control
          void IC1FlexGridRowDetail.Setup(C1FlexGrid parentGrid, int rowIndex)
            {
                var bs = new BindingSource(parentGrid.DataSource, parentGrid.DataMember);
                bs.Position = parentGrid.Rows[rowIndex].DataIndex;
                DataField = "Notes";
                DataSource = bs;
            }
            
          // Used to update size of the FlexGrid detail control
          void IC1FlexGridRowDetail.UpdateSize(C1FlexGrid parentGrid, int rowIndex, Size proposedSize)
            {
                var srSz = parentGrid.ScrollableRectangle.Size;
                var sz = TextRenderer.MeasureText(Text, Font, srSz, TextFormatFlags.WordBreak);
                sz.Width = Math.Max(sz.Width, srSz.Width);
                Size = sz;
            }   
         }                                  
    
        Private Sub CustomSample_Load(ByVal sender As Object, ByVal e As EventArgs)
            flexGrid.DataSource = DemoDataSource("Employees")
            flexGrid.RowDetailProvider = Function(g, r) New CustomRowDetail()
            flexGrid.RowDetailsVisibilityMode = RowDetailsVisibilityMode.VisibleWhenSelected
            flexGrid.Cols("Notes").Visible = False
        End Sub
    
    
        ' Custom row detail class which shows label with notes about employee       
        Public Class CustomRowDetail
            Inherits C1Label
            Implements IC1FlexGridRowDetail
    
    
            ' Used to setup control before showing the FlexGrid detail control
            Private Sub Setup(ByVal parentGrid As C1FlexGrid, ByVal rowIndex As Integer)
                Dim bs = New BindingSource(parentGrid.DataSource, parentGrid.DataMember)
                bs.Position = parentGrid.Rows(rowIndex).DataIndex
                DataField = "Notes"
                DataSource = bs
            End Sub
    
    
            ' Used to update size of the FlexGrid detail control
            Private Sub UpdateSize(ByVal parentGrid As C1FlexGrid, ByVal rowIndex As Integer, ByVal proposedSize As Size)
                Dim srSz = parentGrid.ScrollableRectangle.Size
                Dim sz = TextRenderer.MeasureText(Text, Font, srSz, TextFormatFlags.WordBreak)
                sz.Width = Math.Max(sz.Width, srSz.Width)
                Size = sz
            End Sub
        End Class      
    
    See Also