Click here to Skip to main content
15,891,864 members
Articles / Desktop Programming / WPF
Tip/Trick

Creating a Multi-header Column, XamDataPresenter

Rate me:
Please Sign up or sign in to vote.
4.60/5 (5 votes)
11 Feb 2015CPOL2 min read 10.6K   4  
This tip will help you to display data using XamDataPresenter (or any DataGrid) which will have multi-header column.

Introduction

This tip will help the audience who might have/had some difficulty in creating a multi-header column in XamDataPresenter or XamDataGrid ( Infragistics Controls).

Background

I had some difficulty in creating a multi-header column, so I thought it's worth sharing the idea which I used to overcome the problem. In my case, I was getting the data & header in the form of two XML strings, which I had to parse and generate a data table which is then binded to the datagrid in this case it's XamDataPresenter.

But as we all know that a DataTable can have only a single Column row, so I have made use of FieldLayoutInitializing event of XamDataPresenter in initializing the fields and generating the multi-header column.

The multi-header is achieved in Infragistics using the concept of Unbound Fields & Bounded Fields.

  • Unbound Fields are not bound to a data source. The value shown in the unbound column is calculated in the code-behind.
  • Bound Fields are those which are binded with the Data Table.

Using the Code

In this section, we will see step by step how I overcome the problem of multi-header column.

In my case, I was getting the data & header in the form of two XML strings.

The header XML will have the data of the number of header rows that would be present in the DataGrid(XamDataPresenter).

Header XML string will be parsed and stored in the list as shown below:

C#
private IList<XmlRow> _headerRows = new List<XmlRow>();
      public IList<XmlRow> headerRows
      {
          get
          {
              return _headerRows;
          }
          set
          {
              _headerRows = value;
          }
      }

XmlRow class will have the details of all the header rows that will be present in the header rows,

C#
public class XmlRow
  {
      private IList<XmlColumn> _columnList = new List<XmlColumn>();
      public IList<XmlColumn> columnList
      {
          get
          {
              return _columnList;
          }
          set
          {
              _columnList = value;
          }
      }

      public void addColumn(XmlColumn xmlColumn)
      {
          columnList.Add(xmlColumn);

      }

  }

XmlColumn will have the values of the Attributes present in the XML string:

C#
public class XmlColumn
   {
       private string _id = "";
       public string id
       {
           get
           {
               return _id;
           }
           set
           {
               _id = value;
           }

       }

       private string _value = "";
       public string value
       {
           get
           {
               return _value;
           }
           set
           {
               _value = value;
           }

       }

       private int _span = 1;
       public int span
       {
           get
           {
               return _span;
           }
           set
           {
               _span = value;
           }

       }

       private string _type = "";
       public string type
       {
           get
           {
               return _type;
           }
           set
           {
               _type = value;
           }

       }

       private string _format = "";
       public string format
       {
           get
           {
               return _format;
           }
           set
           {
               _format = value;
           }

       }

       private string _cellColor = "";
       public string cellColor
       {
           get
           {
               return _cellColor;
           }
           set
           {
               _cellColor = value;
           }

       }

       private string _fieldColor = "";
       public string fieldColor
       {
           get
           {
               return _fieldColor;
           }
           set
           {
               _fieldColor = value;
           }

       }

   }

Now the data table is generate from the last XML row in the header XML which will be used to create the columns of the Data Table which in turn will be binded to the XamDataPresenter directly.

The below code shows how the columns of the data table is generated.

C#
 DataTable dataTable = new DataTable();
foreach (XmlColumn column in dataHeader.Last<XmlRow>().columnList)
{
    string columnType= column.type;
    switch (columnType.ToUpper())
    {
        case "STRING":
            dataTable.Columns.Add(column.id, typeof(string));
            break;
        case "DATE":
            dataTable.Columns.Add(column.id, typeof(DateTime));
            break;
        case "BOOL":
            dataTable.Columns.Add(column.id, typeof(bool));
            break;
        case "DOUBLE":
            dataTable.Columns.Add(column.id, typeof(double));
            break;
        case "PERCENTAGE":
            dataTable.Columns.Add(column.id, typeof(double));
            break;
        case "DECIMAL":
                dataTable.Columns.Add(column.id, typeof(decimal));
            break;
        case "NUMBER":
            DataColumn columnValue = new DataColumn();
            columnValue.DataType = typeof(double);
            columnValue.AllowDBNull = true;
            columnValue.ColumnName = column.id;
            dataTable.Columns.Add(columnValue);
            break;
        case "INT":
                dataTable.Columns.Add(column.id, typeof(Int32));
            break;
    }
}

After this, the data is added to the data table using the data XML.

Once the Data Table is ready, it is binded to the XamDataPresenter, in the FieldLayoutInitializing event of the XamDataPresenter the unbounded Fields are generated in the code-behind as shown in the below code:

C#
private void XamDataPresenter_FieldLayoutInitializing
    (object sender, Infragistics.Windows.DataPresenter.Events.FieldLayoutInitializingEventArgs e)
{
    try
    {
        e.FieldLayout.Settings.AutoGenerateFields = false;
        e.FieldLayout.Settings.AutoArrangeCells = AutoArrangeCells.Never;
        //getHeaderRows method will give us the header XML
        int rowCount = rpgvm.getHeaderRows().Count;
        dummyPositions = new int[rowCount];

        for (int rowIndex = 0; rowIndex < rowCount; rowIndex++)
        {
            XmlRow row = rpgvm.getHeaderRows()[rowIndex];
            int columnIndex = 0;
            if (rowIndex != (rowCount - 1))
            {
                foreach (XmlColumn column in row.columnList)
                {
                    UnboundField ubf = new UnboundField
                    {
                        Name = column.id,
                        Label = column.value,
                        Row = rowIndex,
                        Column = columnIndex,
                        ColumnSpan = column.span,
                        Width= FieldLength.Auto,
                    };
                    ubf.Settings.CellMaxHeight = 0.00;
                    e.FieldLayout.FieldSettings.LabelTextAlignment = TextAlignment.Center;
                    e.FieldLayout.FieldSettings.AllowGroupBy = true;
                    e.FieldLayout.Settings.RecordSelectorLocation = RecordSelectorLocation.None;
                    e.FieldLayout.Fields.Add(ubf);

                    if (column.span > 1)
                    {
                        columnIndex = columnIndex + column.span;
                    }
                    else
                    {
                        columnIndex++;
                    }
                }
            }
            else
            {
                foreach (XmlColumn column in rpgvm.getHeaderRows().Last<XmlRow>().columnList)
                {
                    Field fld = new Field
                    {
                        Name = column.id,
                        Label = column.value,
                        Row = rowIndex,
                        Column = columnIndex,

                    };
                    fld.Settings.AllowRecordFiltering = true;
                    fld.Settings.FilterLabelIconDropDownType =
            FilterLabelIconDropDownType.MultiSelectExcelStyle;
                    // Stops the movement of Column from the Grid
                    e.FieldLayout.Settings.AllowFieldMoving = AllowFieldMoving.No;
                    //Disable the Record selection location
                    e.FieldLayout.Settings.RecordSelectorLocation = RecordSelectorLocation.None;
                    //Field Should not be editable
                    e.FieldLayout.FieldSettings.AllowEdit = false;
                    //Setting the Filter in the Label itself
                    e.FieldLayout.Settings.FilterUIType = FilterUIType.LabelIcons;
                    columnIndex++;
                }
            }
        }
    }
    catch (Exception ex)
    {
        Logger.Error(ex, "XamDataPresenter_FieldLayoutInitializing");
    }
}

Though this is a very small work, I sure hope this will help somebody. :)

Points of Interest

With the help of Unbound Field, we can play with the XamDataPresenter in a much more flexible manner. Formatting of the fields can we done easily in the FieldLayoutInitializing event as shown in the above example.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
Software Engineer, Loves cooking Indian food & Going for long drives

Comments and Discussions

 
-- There are no messages in this forum --