Saturday, October 2, 2010

CUSTOM CONTROLS IN ASP.NET - GRIDVIEW

In Asp.net, we generally bind GridView with a data source. That data source can be anything like – Data Table, Data View, Class Object, etc. If data source contains some value then it simply binds the grid and displays the records according to grid formatting.
What happens when data source is empty? – GridView will not get displayed.
If suppose, we want to display header and footer of grid in each and every case then what should we do?
One way is to manipulate the data source and add a blank row in it and bind it with grid. It will display the header and footer along with a blank row in grid. This is dirty coding.
Another way is custom controls. Before moving to custom controls first understand the workflow of Grid View.
Steps to create a GridView custom control and use it in aspx page:
1. Take a class and declare a namespace.
2. Inherit your class with GridView (System.Web.UI.WebControls.GridView) class:
using System;
using System.Collections;
using System.Data;
using System.Web.UI.WebControls;

namespace AlwaysShowHeaderFooter {
public class GridViewAlwaysShow : GridView {
}
}
3. Add a delegate above the class:
public delegate IEnumerable MustAddARowHandler(IEnumerable data);

4. Add an event inside the class:
public event MustAddARowHandler MustAddARow;

5. Create a Method to raise this event:
protected IEnumerable OnMustAddARow(IEnumerable data) {
if (MustAddARow == null) {
throw new NullReferenceException("The datasource has no rows. You must handle the \"MustAddARow\" Event.");
}
return MustAddARow(data);
}

6. Now come to main aspx page where you want to display the grid. Register your custom control namespace here:
<%@ Register TagPrefix="Custom" Namespace="AlwaysShowHeaderFooter" %>

7. Add your custom grid on page and call OnMustAddARow function:
OnMustAddARow="grdCustom_MustAddARow"

8. Now define the grdEmail_MustAddARow() in aspx.cs file:
//Flag used to identify if the datasource is empty.
bool _isEmpty = false;

///
/// Handles the MustAddARow event of grdEmail
///

/// The data.
///
protected IEnumerable grdEmail_MustAddARow(IEnumerable data)
{
ListDictionary ldEmails = (ListDictionary)data;
ldEmails.Add("", "");
_isEmpty = true;
return ldEmails;
}
Here we have set a flag _isEmpty = true to check if data source is empty.
I have bind the grid with ListDictionary, you can take any data source.

9. Come back to your custom control class and override the OnDataBound() method to check if data source is empty. As we have added a dummy(blank) row in grdEmail_MustAddARow(), it will display a blank row in grid at runtime which should not come. So we will hide it.
protected override void OnDataBound(EventArgs e)
{

//if in DesignMode, don't do anything special. Just call base and return.
if (DesignMode)
{
base.OnDataBound(e);
return;
}

//hide the dummy row.
if (_isEmpty)
{
Rows[0].Visible = false;
}
base.OnDataBound(e);
}

10. GridView have a method protected internal override void PerformDataBinding(IEnumerable data) which gets called through Databind() method of GridView.

11. Now override the PerformDataBinding method to call OnMustAddARow method if data source is blank. This method gets called from databind() method of GridView.
protected override void PerformDataBinding(IEnumerable data)
{

//If in DesignMode, don't do anything special. Just call base and return.
if (DesignMode)
{
base.PerformDataBinding(data);
return;
}

//Count the data items.(I wish I knew a better way to do this.)
int objectItemCount = 0;
foreach (object o in data)
{
objectItemCount++;
}

//If there is a count, don't do anything special. Just call base and return.
if (objectItemCount > 0)
{
base.PerformDataBinding(data);
return;
}

//Set these values so the GridView knows what's up.
SelectArguments.TotalRowCount++;
_isEmpty = true;

//If it's a DataView, it will work without having to handle the MustAddARow event.
if (data.GetType() == typeof(DataView))
{
//Add a row and use that new view.
DataView dv = (DataView)data;
dv.Table.Rows.InsertAt(dv.Table.NewRow(), 0);
base.PerformDataBinding(dv.Table.DefaultView);
return;
}
else
{
//If you are using some custom object, you need to handle this event.
base.PerformDataBinding(OnMustAddARow(data));
return;
}
}

That’s it!! Your custom control is ready to run...:)
Bookmark and Share

No comments:

Post a Comment