Sep 22 2006

Insert user control every N records in gridview

Posted by admin under Controls

This will show you a technique to modify the layout of a gridview. Basically what we will do is insert an extra row to our gridview every 5 records - and in that row we will dynamically load a usercontrol.

As you can see our usercontrol is really simple - just an image and a text:

I have seen a lot of solutions like this and most of them involves trying to dynamically add a TableRow to the grid. I take another approach - by modifying the datatable instead.

Just throw up a gridview into your designer:



        <asp:GridView ID="GridView1" runat="server" OnRowCreated="GridView1_RowCreated">
        </asp:GridView>


Now lets look at the Page_Load event:



    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string sConnString = ConfigurationManager.ConnectionStrings["NorthwindConn"].ConnectionString;

            DataSet ds = Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteDataset(
                sConnString,
                CommandType.Text,
                "select * from suppliers order by supplierid");

            int nRowCount = 0;
            DataTable dt = ds.Tables[0];
            DataTable dt2 = dt.Clone();
            dt2.Clear();
            foreach (DataRow row in dt.Rows)
            {
                dt2.ImportRow(row);
                nRowCount++;
                if (nRowCount == 5)
                {
                    DataRow rowNew = dt2.NewRow();
                    rowNew["supplierid"] = -12345;
                    dt2.Rows.Add(rowNew);
                    nRowCount = 0;
                }
            }
            GridView1.DataSource = dt2;
            GridView1.DataBind();


        }


FIrst we read our dataset from the Northwind database  into a dataset. We then create a new DataTable (dt2). What we will do is loop through the records from the database and move them (Import row) into our dt2 - but after each 5 records we will insert an extra datarow - and we flag it my setting "supplierid" to -12345.

This would create a datatable with some extra "fake" records - and in our RowCreated we will then be able to find these records and treat them differently. The good things about this solution is that it's pretty straightforward - RowCreated will be called once for each row we want to render on the screen:

Now lets look at RowCreated event:



    protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            DataRowView oRow = e.Row.DataItem as DataRowView;
            if (Convert.ToInt32(oRow["supplierid"]) == -12345)
            {
                int nCount = e.Row.Cells.Count;
                e.Row.Cells.Clear();
                TableCell oCell = new TableCell();
                e.Row.Cells.Add(oCell);
                e.Row.Cells[0].Attributes["colspan"] = nCount.ToString();
                e.Row.Cells[0].Controls.Add(LoadControl("testUC.ascx"));
            }
        }
    }

Remember - it's being called for all records (even for our fake ones ) - and we start by checking for the fake supplier id. If found - we know we have found a fake row - and now we should insert our user control (testUc.ascx).

But - we need some special stuff here. We want to show this row with just one single cell (colspan=all columns in the dataset) - so  we first save the original number of tablecells (int nCount = e.Row.Cells.Count;).

Next we remove all cells, create one new single TableCell - add it to the row - and sets the colspan attribute to the original number of cells.

Last we just load the usercontrol into our cell.

This is pretty useful if you have a long list to display - and you might want to insert some special code (maybe google adsense ad) after a certain number of rows.

Last I want to say - these types of tricks are only possible by coding - so please read our article serie on using controls rather than design time controls cause you will soon see that with code you can do almost anything!