[Download Code]
The client wants to navigate thru the DataGrid Products horizontally and anchor the first column containing the Feature descriptions. We could implement horizontal scrolling using a DIV tag, but anchoring the first column becomes more problematic. Since our client wants to Page thru the Products, we can simply bind the appropriate columns to the DataGrid based on the DataGrids's current PageIndex. Since the DataGrid doesn't really support this type of paging, we'll implement our own Page navigation buttons, and maintain the current PageIndex in the ViewState.
In the code snippets below, assume there is a "Previous Page" button named prevBtn, and a "Next Page" button named nextBtn. There is also a property named PageIndex that maintains the currently selected page index and is set when the previous and next buttons are clicked. When the page loads the first time, the PageIndex is set to zero and the BindHorzGrrd method is called. In subsequent PostBacks, the nextBtn and prevBtn modify the current PageIndex and then call the BindHorzGrid method.
The first part of the BindHorzGrid method simply sets up some values that we'll need to decide which columns should be displayed for the current PageIndex. We also enable/disable our navigation buttons depending on the presence of either previous pages or next pages.
private void BindHorzGrid()
{
const int pageSize = 3;
// constant number of columns displayed in each page
int colCount = pivotTbl.Columns.Count - 1;
int pageMax = colCount / pageSize;
if ( PageIndex >= pageMax ) PageIndex = pageMax;
else if ( PageIndex < 0 ) PageIndex = 0;
prevBtn.Enabled = ( PageIndex > 0 );
nextBtn.Enabled = ( PageIndex < pageMax );
The remainder of this method creates the DataGrid's BoundColumns that reflect the correct columns from our pivoted DataTable. We first clear the Columns collection and then add the first column representing the Features. The remaining columns are added starting with the (zero based) PageIndex * pageSize (number of columns per page). The final step is to supply the DataSource and then DataBind the grid and our pivot table.
pageGrid.Columns.Clear();
// frist create the "anchored" column[0] -- Product
BoundColumn c = new BoundColumn();
c.HeaderText = pivotTbl.Columns[0].ColumnName;
c.HeaderStyle.Font.Bold = true;
c.DataField = pivotTbl.Columns[0].ColumnName;
c.ItemStyle.Font.Bold = true;
pageGrid.Columns.Add( c );
// now create the bound columns for this page's set of columns
int count = 0;
for( int i = PageIndex * pageSize; count < pageSize && i < colCount; i++, count++ )
{
c = new BoundColumn();
c.HeaderStyle.Width = Unit.Pixel( 100 );
c.ItemStyle.Width = Unit.Pixel( 100 );
c.HeaderText = pivotTbl.Columns[ i + 1 ].ColumnName;
c.DataField = pivotTbl.Columns[ i + 1].ColumnName;
pageGrid.Columns.Add( c );
}
// now bind the grid to our new bound columns
pageGrid.DataSource = pivotTbl;
pageGrid.DataBind();
}
If you download the source code, you'll see that I depend on formatting the columns using the DataGrid's ItemDataBound event handler. Since all of the pivot table's DataColumns are of type String, I may need to parse the data value depending on the Column being bound.