Friday, February 12, 2010

Bubbling up events from user control to parent page/control

It is a good practice to use user controls when same controls are repeated in many pages. But there are some cases where the user control has some controls which generate events and those need to be handled by the containing page/user control. For eample there is a button control in the user control and you want to do something in parent page/control when the button in user control is clicked. In this case

1.You need to define an event handler in user conrol as shown below.

public partial class UC_Pagination : System.Web.UI.UserControl
{
...
...

public event EventHandler PageIndexChanged;
...
...
...
}


2. You need to call the event explicitly in the user control's implementation of the event handler of button click as shown here

public partial class UC_Pagination : System.Web.UI.UserControl
{
...
...
protected void Button1_Click(object sender, EventArgs e)
{
...
...
PageIndexChanged(sender, e);
...
...
}
...
...
...
}

3. Implement the event handler bubbled up by user control in the parent page/control in its own way as usual (shown below).


public partial class Coaches : System.Web.UI.Page
{
...
...
protected void ucPaginationPageIndexChanged(object sender, EventArgs e)
{
...
...
...
}

...
...
}

kick it on DotNetKicks.com
Shout it

How to implement paging with LINQ

Before going into how paging is implemented with LINQ, Let's discuss the need for implementing paging.

With large amounts of data, it is not a good practice to pull all records from database when you are showing a fraction of them in one page. It is always recommended to use data on demand approach. When you want to show first 20 records out of the search results then you must get the first 20 records from database and discard the rest. Similarly when you want to show next 20 records of the search results then you need to get the next 20 records from database and discard the rest. This is nothing but called paging.

LINQ has made the paging solution very simple as shown below example.

public List<Client>
GetAllClients(bool? isActive, int pageNumber, int pageSize, out int totalPages)
{
//Actual query which returns large data
var query = dataContext.Clients.Where(p => isActive == null || p.IsActive == isActive);

//Calculating total number of pages by taking ceiling number of the fractional value
totalPages = (int)Math.Ceiling((decimal)query.Count() / (decimal)pageSize);

//Paging logic goes here
return query.Skip((pageNumber - 1)*pageSize).Take(pageSize).ToList();
}


The parameters which play major role in paging are page number and page size. The page number is to identify the page of which the records to be returned. And the page size to identify the number of records to be returned. And there is another out parameter totalPages which is used to hold the total number of pages available within the data returned. This is needed to show the number of pages to the user and also useful in the logic which enables/disables page navigation.
Shout it
kick it on DotNetKicks.com