Dynamic Rating System Part 2: Postback...

Postback functionality is added by implementing the IPostBackEventHandler interface; this interface maps a client-side event to a server-side event by raising the appropriate server event in the RaisePostBackEvent method. Using an event argument, this method has the capabilities to call more than one event if that complexity is needed.


By: Brian Mains Date: March 10, 2005 Download the code.

Part 1 of this series focused on the basic rendering of the DynamicRatingSystem control, and adding DHTML functionality to a server control. This article will focus on adding postback functionality to the control. Postback functionality is added by implementing the IPostBackEventHandler interface. The objects interacting with postback capabilities are the SelectedRating property and the SelectedRatingChanged event.

IPostBackEventHandler maps a client-side event to a server-side event. For example, the Button server control has a click event, which is mapped to the clicking of an HTML submit button on the client side. The Page.RegisterPostBackEventReference method creates a JavaScript method call, posting back to the server, and calling the IPostBackEventHandler.RaisePostBackEvent on the server-side. Whatever postback functionality is desired is handled by this method in the server control. In this example, the RaisePostBackEvent method will indirectly raise the SelectedRatingChanged event, which then wires up to the page or user control. The event reference passed from the client to the server is the index number of the selected rating (not zero-based but specified by the range).

Let's look at the objects that will be involved in the postback functionality. The SelectedRating property stores the selected rating in the control. The value is not persisted in ViewState because the user can only click the rating once per postback, and thus storing the property in ViewState may incorrectly select a rating after multiple postbacks. For simplicity stake, this control will allow the lack of state management to clear the selected rating.

private int _selRating;
public int SelectedRating {
  get {
    return _selRating;
  }
  set {
    _selRating = value;
  }
}

The event that fires when the rating changes is named SelectedRatingChanged. This event fires by clicking the image on the client side. The event uses the following property-style syntax, instead of declaring a field for each event. This is more efficient, as it doesn't use up as many resources and it doesn't have locking issues. In VB.NET, this option is not available. The _changed variable stores the key that retrieves the event handler from the Events collection.

private static readonly object _changed = new Object();
public event EventHandler SelectedRatingChanged {
  add {
    Events.AddHandler(_changed, value);
  }
  remove {
    Events.RemoveHandler(_changed, value);
  }
}

Each event usually has a protected method named On<event name> to fire the event, which is defined in this control as OnSelectedRatingChanged. This method returns the appropriate event handler from the Events collection, and calls it.

protected void OnSelectedRatingChanged(EventArgs e) {
  EventHandler events = (EventHandler)Events[_changed];
  if (events != null)
    events(this, e);
}

To raise the event in the first place, the IPostBackEventHandler.RaisePostBackEvent method calls OnSelectedRatingChanged when the page posts back through the client-side clicking of the image. The RaisePostBackEvent method accepts an event argument, passed in from the client, which in this case will be the selected rating integer value. The integer value will be a valid value that exists within the Minimum/Maximum range values supplied for the control. The SelectRating property will have the correct rating value before the event is fired.

void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {
if (eventArgument != null && eventArgument.Length > 0)
  _selRating = int.Parse(eventArgument);

OnSelectedRatingChanged(EventArgs.Empty);
}

The original design of the control in Part 1 contains the code to the RenderContents method, which is also included in the code sample for this article. Only one line of code had been added for the onclick event. Each image will have an onclick DHTML event that is supplied from the GetPostBackEventReference method of the Page class. This method calls the appropriate JavaScript function that is predefined in the .NET framework. This method accepts an event argument to distinguish between the selected image that has been clicked, through the selected rating, which is determined as the control images are rendered in RenderContents.

writer.AddAttribute("onclick", Page.GetPostBackEventReference(this, i.ToString()));

In the page, the selected rating value is rendered in a label. The label has a simple message stating the value. Click the rating items to see what the selected rating is. To link a client-side event to a server-side event doesn’t involve much code, and adds a sizable amount of functionality to the control.

You may download the code here.