So what does it take for our pager to really work? Not so much really – you just need to describe the delegate, define the event in the control, and, if necessary, describe the structure that passes data to the event handler. And we’ll start by declaring a delegate.
A delegate is essentially a pointer to a function in C++terms. For delegates that define events in server controls, additional restrictions are imposed : such a delegate must accept 2 parameters, the first of which must be of the object type (it passes a reference to the object that generated this event), and the second – of the EventArgs type (this parameter passes additional information related to the event being called). The EventArgs class is the base class for all classes that transmit additional information. It does not contain any properties for transmitting information by itself.It is used in cases where an event simply announces that it has occurred (for example, the Click event of the server Button control). In our case, we need to pass additional data in the event – a new page number. Therefore, to pass this data, we will define a class that inherits the EventArgs class.
public class PagerEventArgs : EventArgs
{
public int SelectedPage;
public PagerEventArgs(int SelectedPage)
{
this.SelectedPage = SelectedPage;
}
}
After that, declaring a delegate for our event doesn’t pose any problem:
public delegate void PagerEventHandler(Object sender, PagerEventArgs e);
And, accordingly, we will add a property of this type to our class.
public class Pager : WebControl
{
public event PagerEventHandler Navigate;
...
}
Now we must turn again to the theory. We need our control to first be able to generate postbacks, and secondly be able to receive and process postback information. You also need to transmit information about the page number that triggered the postback when you click on it. And there is such a possibility, moreover, it takes 5 minutes to implement it in our control:).
Remember that in the previous article, when drawing <a> tags, I used a dummy to fill in the href tag? It’s time to fix this and add a call to the klent function that generates a postback. To do this, use the Page methods.GetPostBackEventReference или Page.GetPostBackClientHyperlink (these methods work almost identically, the only difference is that GetPostBackClientHyperlink adds the string “javascript:” to the beginning of the returned string). these methods take 2 parameters: a pointer to the control that generates the postback, and a string with additional information. In our case, the values of these parameters will be the link this and the page number of the link. Accordingly, now the code that outputs the page number will look like this:
output.AddAttribute(HtmlTextWriterAttribute.Href, Page.GetPostBackClientHyperlink(this, (pgIndex - 1).ToString()));
output.RenderBeginTag(HtmlTextWriterTag.A);
output.Write(pgIndex.ToString());
output.RenderEndTag();
To get a postback, too, you don’t need much work – you just need to implement the IPostBackEventHandler interface in our control panel. I.e., implement the RaisePostBackEvent method of this interface. This method accepts a single parameter – a string containing additional data that we defined when calling the Page method.GetPostBackClientHyperlink.Now all we have to do is get this data (after all, this parameter contains the number of the selected page) and call the event.
But first, let’s define a separate method that checks for the presence of an attached event handler and calls it if there is a handler. This method is usually prefixed with On before the event name:
protected virtual void OnNavigate(PagerEventArgs e) { if (Navigate != null) Navigate(this, e); }
And only now we are implementing the RaisePostBackEvent method
public void RaisePostBackEvent(string arg)
{
int cmd = Int32.Parse(arg);
PagerEventArgs e = new PagerEventArgs(cmd);
CurrentPage = cmd;
OnNavigate(e);
}
This completes the process of implementing the functionality of our pager. You can download the full code of the control from the link at the end of the article.
In this article, I described only a small part of the issues related to developing your own controls and did not say anything at all about many other aspects of this problem. But I can name them and try to show you approximate ways to solve them:). So in addition to generating events based on the postback of the control, there are also issues of data processing during postback (the IPostbackDataHandler interface), saving/restoring the state of controls during postback (the LoadViewState and SaveViewState methods), problems and solutions for implementing a large number of events in the class (the EventHandlerList class), and template controls. A separate large piece of creating controls is also creating designers. But all these are topics for individual articles, which I may also be going to write sometime:).