Smart ListControl in ASP.NET 1.x/2.0
page 4 of 7
by Bilal Haidar
Feedback
Average Rating: 
Views (Total / Last 10 Days): 37990/ 68

Implement IPostBackDataHandler

The IPostBackDataHandler contains two main methods:

IPostBackDataHandler.RaisePostDataChangedEvent

IPostBackDataHandler.LoadPostData

How are those two methods used when they are being implemented in a control?

Although this question is not the topic of this article, we are going to give a brief overview of what happens when the Page builds its control tree and how each control fires specific events based on the interfaces it implements.

When a post back happens, the Page recreates its tree of controls.  It starts from the main control, which is the Page itself, then for the children controls and the same continues for the sub children controls.

For each control it is being checked whether it implements some interfaces or not.  Among those interfaces is the IPostBackDataHandler.  If this interface is implemented, this means that the control has implemented the above mentioned two methods.

Those methods are usually implemented to handle any posted back data.  By default, in ASP.NET the ListBox implements the above two methods.

The LostPostData is being implemented to detect the selected index or indices in case the ListBox is configured to be in the Multiple Selection mode.

What we will do is implement the LoadPostData method.  First of all, we well keep the default behavior of this method, where we detect the selected index or indices and we will get the data stored in both Hidden Fields mentioned above.

The data stored in those two Hidden Fields will be used to remove items from the ListBox and, in this case, the _REMOVED Hidden Field is queried to get all the item indices to remove from the ListBox.  The _ADDED Hidden Field is queried to get all the items that will be added to the Items collection of the ListBox.

The code below shows the implementation of the LoadPostData.

Listing 4

bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection
  postCollection)
{
// Handle the SelectedIndex or Indicies
  string[]postedItems = postCollection.GetValues(postDataKey);
  bool returnValue = false;
 
// If no selection is done on the client side
  if (postedItems == null)
  {
    if (this.SelectedIndex !=  - 1)
    {
      returnValue = true;
    }
 
// No further processing for the Selected Index/Indicies
    goto HandleClientChanges;
  }
 
// If selection is in single mode
  if (this.SelectionMode == ListSelectionMode.Single)
  {
    if (postedItems != null)
    {
// Process first item, since we have a single selection
// ListItem item = this.FindByValueInternal(postedItems[0]);
      int index = this.FindByValueInternal(postedItems[0]);
        //Items.IndexOf(item);
      if (this.SelectedIndex != index)
      {
// Change occurred
        this.SelectedIndex = index;
        returnValue = true;
      }
    }
  }
 
// Else, the selection mode is multiple
  int numberOfItemsSelected = postedItems.Length;
 
// Old selected items
  ArrayList oldSelectedItems = this.SelectedIndicesInternal;
 
// An empty arraylist of the currently selected items on the clisnde side
  ArrayList currentlySelectedItems = new ArrayList(numberOfItemsSelected);
 
// Fill in all the indicies of the posted selected items
  for (int i = 0; i < numberOfItemsSelected; i++)
  {
    currentlySelectedItems.Add(this.FindByValueInternal(postedItems[i]));
  }
 
// Get the number of currently selected indicies
  int numberOfSelectedItems = 0;
  if (oldSelectedItems != null)
  {
    numberOfSelectedItems = oldSelectedItems.Count;
  }
 
// Check if both numbers are equal
  if (numberOfItemsSelected == numberOfSelectedItems)
  {
    for (int j = 0; j < numberOfItemsSelected; j++)
    {
      int oldSelect = Convert.ToInt32(currentlySelectedItems[j]);
      int currentSelect = Convert.ToInt32(oldSelectedItems[j]);
 
      if (oldSelect != currentSelect)
      {
// Explicitly mark the item selected
        this.Items[j].Selected = true;
        returnValue = true;
      }
    }
  }
  else
  {
// The number of selected items has changed
    returnValue = true;
  }
 
// Reset all selections to the newly selected items
  if (returnValue)
  {
    this.SelectInternal(currentlySelectedItems);
  }
 
 
// Section to handle ADDED and REMOVED Items.
  HandleClientChanges:
 
// Remove the items from the Items collection
// that were marke for deletion on client side// Handle items added on Client Side
  string itemsRemoved = postCollection[this.HFItemsRemoved];
  string[]itemsRemovedCol = itemsRemoved.Split(',');
  if (itemsRemovedCol != null)
  {
    if ((itemsRemovedCol.Length > 0) && (itemsRemovedCol[0] != ""))
    {
      for (int i = 0; i < itemsRemovedCol.Length; i++)
      {
        ListItem itemToRemove = this.Items.FindByValue(itemsRemovedCol[i]);
 
// Remove from the Items Collection
        Items.Remove(itemToRemove);
      }
      returnValue = true;
    }
  }
 
// Handle items added on Client Side
  string itemsAdded = postCollection[this.HFItemsAdded];
  string[]itemsCol = itemsAdded.Split(',');
  if (itemsCol != null)
  {
    if ((itemsCol.Length > 0) && (itemsCol[0] != ""))
    {
// counter to validate returnValue
      int counter =  - 1;
      for (int i = 0; i < itemsCol.Length; i++)
      {
        string buf = itemsCol[i];
        string[]itemsTokens = buf.Split('|');
 
// Check if already added to the collection
        ListItem it = this.Items.FindByValue(itemsTokens[1]);
        if (it == null)
        {
          string text = itemsTokens[0];
          string id = itemsTokens[1];
          ListItem item = new ListItem(text, id);
          Items.Add(item);
 
// Updata counter
          counter++;
        }
      }
      returnValue = counter >  - 1 ? true : false;
    }
  }
 
  return returnValue;
}

The first set of code lines behaves as the code written for the LoadPostData of the ListBox that ships with ASP.NET.

The second part retrieves all the indices that are listed in the Hidden Field to be removed from the ListBox.

The third part retrieves all the item pairs (Text and Value) that are found in the Hidden Field used to represent the items to be added to the Items collection of the ListBox.

There is not much to be said about the RaisePostDataChangedEvent method.  The implementation is simple.

Listing 5

void IPostBackDataHandler.RaisePostDataChangedEvent()
{
  OnSelectedIndexChanged(EventArgs.Empty);
}

What happens after the Page_Load method is fired?  The result of execution of the LoadPostData, which returns a Boolean value, is checked.  If the value if true, this means that the selected indices has changed and, therefore, the need to raise the even called OnSelectedIndexChanged.

On the other hand, if LoadPostData method returned a value of false, this means that the selected indices have not been changed and then there is no need to fire the OnSelectedIndexChnaged.

With the above said, we have finished implementing the new smart ListBox control.  In the next section we will see an example on how to use this control on a web form and how to call the JavaScript utility methods mentioned in a previous section.


View Entire Article

User Comments

Title: Re:   
Name: Bilal Hadiar [MVP]
Date: 2007-04-04 1:51:36 AM
Comment:
Hello,
I have updated the control to work on other browsers than IE!
Check my post here:
http://bhaidar.net/cs/archive/2007/04/03/xlistbox-and-mover-control.aspx
Title: Re:   
Name: Bilal Haidar [MVP]
Date: 2006-12-09 6:40:35 AM
Comment:
Hello:
If it is not working on those two browsers, means there is something in the JavaScript that is specific for the IE only!
Let me check what I can do and come back to you!

Regards
Title: Re:   
Name: Bilal Hadiar [MVP]
Date: 2006-12-06 1:54:05 AM
Comment:
Hello, what exactly is happening? I don't have Safari here, all my work in the company is IE that is why I didn't test it there!

Regards
Title: Safari / doesnt work   
Name: Sonu Kapoor
Date: 2006-12-05 3:19:28 PM
Comment:
It doesnt work properly on safari!






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-25 7:15:35 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search