user107986
user107986

Reputation: 1541

Is it possible to specify the event to fire?

A pretty detailed explanation of how a postback mechanism works can be found here.

In ASP.NET the controls usually have many events. For example the LinkButton class has Click event.

The following code:

<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click" Text="LinkButton" />

is translated to this on client side:

<a id="LinkButton1" href="javascript:__doPostBack('LinkButton1','')">LinkButton</a>

As you can see, the client's code doesn't specify the event to fire or the event handler.

So my question is, how the server knows it should fire the Click event and LinkButton1_Click event handler, if the only thing it receives from the client is the component's ID (the first parameter of __doPostBack method)?

What if I wanted the component to fire a different event than Click?

Upvotes: 1

Views: 305

Answers (2)

JotaBe
JotaBe

Reputation: 39055

ASP.NET Web Forms always creates a form which includes all the controls in the page. Whenever the user clicks a control in the page that triggers an event in the server, what is happening behind the scenes is that the form is being posted to the server. Instead of doing a simple POST, the post is done by the client side __doPostback function, which receives two parameters: eventTarget and eventArgument. The first has the ID of the control which triggers the postback, and the the second contains any extra information. The vañlues of these parameters are copied to two hidden fields in the form, which are posted with the rest of the form's controls

Once in the server, the values in this controls can be read to determine which event is being raised. They can be read by accessing Request["__EVENTTARGET"]; and Request["__EVENTARGUMENT"];

You can read this SO Q&A, and the linked pages, to learn more about it: How to use __doPostBack()

The ASP.NET framework simplifies the work by examining these values, and looking for a control whose ID matches the __EVENTTARGET, and implements IPostBackEventHandler. To learn more about this, you should read: Server Event Handling in ASP.NET Web Forms Pagess.

Apart from the postback events, there are also the "change events". This events are raised by comparing the original value of the control, when it was sent to the browser, and the value posted in that control. For example, a TextBox has a TextChanged event. To determine if the event has to trigger, the server extrat the original value of the control from the view state (a hidden field which was sent to the browser, with the state of all the rednered controls, including their values) and compares it with the posted value, triggering the event if necessary. In a similar fashion to IPostBackEventHandler, implementing IPostBackDataHandler will allow the framework to look for controls which need to handle this kind of events.

You should also understand the page lifecycle to know what happens in the server, and in which order: When to wire up event handlers asp.net

Upvotes: 1

Andrew Savinykh
Andrew Savinykh

Reputation: 26329

The example I'm going to give is useless for any practical purposes, but then, you have not indicated any of your practical purposes, so I think it's a fair game. I hope that it will show the approach to you and then you will be able to modify and extend it you suit your needs.

public class LinkButtonWithClack : LinkButton
{
    private const string ClackMarker = "Clack";
    public bool ClackMode { get; set; }
    protected override PostBackOptions GetPostBackOptions()
    {
        var options = base.GetPostBackOptions();
        if (ClackMode)
        {
            // That's how you specify the event argument for __EVENTARGUMENT
            options.Argument = ClackMarker;
        }
        return options;
    }

    public event EventHandler Clack;

    protected override void RaisePostBackEvent(string eventArgument)
    {
        if (eventArgument == ClackMarker)
        {
            this.OnClack(EventArgs.Empty);
        }
        else
        {
            base.RaisePostBackEvent(eventArgument);
        }          
    }

    protected virtual void OnClack(EventArgs e)
    {
        if (Clack != null)
        {
            Clack(this, e);
        }
    }
}

In this example you are creating a new server control, LinkButtonWithClack. This control inherits from the LinkButton server control and has an additional event, Clack. If you set property ClackMode to true it will start generate Clacks instead of Clicks.

Whether and event a click or clack is communicated by the second argument to doPostBack:

<a id="MainContent_LinkButtonWithClack1" 
href="javascript:__doPostBack(&#39;ctl00$MainContent$LinkButtonWithClack1&#39;,&#39;Clack&#39;)">

Server then examines the contents of it and calls the Clack event if it sees "Clack".

Of course you are unlikely to derive from LinkButton, I'm only using it as an example because you did. You likely will be implementing a server control from scratch. When doing so, please bring all your knowledge on server control creation, or read up if you don't have one - you will need it.

As a side-note, this day it's easier to find help with asp.net mvc than with webforms, since the latter is older and less and less people are using it. If you have any say in technology choice at all I'd choose asp.net mvc over webforms for almost anything.

Upvotes: 0

Related Questions