Events and Virtual methods in System.Web.UI.Page class - c#

I am able to hook the event and also allowed to override load and init.., events in my aspx codebehind file. I have following questions.
public partial class Default : System.Web.UI.Page
{
public Default()
{
this.Init += Default_Init;
this.Load+=Default_Load;
}
protected void Default_Load(object sender, EventArgs e)
{ }
protected void Default_Init(object sender, EventArgs e)
{ }
protected override void OnLoad(EventArgs e)
{ }
protected override void OnInit(EventArgs e)
{ }
}
Qs:
Why such option(both virtual method and event handler) is exist in Page class?
When override methods got executed, my event handlers(Default_Load and Default_Init) are not executed. what is the reason behind?
Should i call base.OnLoad(e); in overridden OnLoad method? Why should/shouldn't I?

By default, OnInit and OnLoad are not handlers of Init and Load events. They are used to Fire Init and Load events.
When you override, you change the behavior of these methods thus, events are not fired by OnInit and OnLoad methods (unless you explicitly write base.OnInit etc.)
If you change the behavior of OnLoad and do not call base method, then you may break the page lifecycle of asp.net application. For instance, Load event will not be called.

Normally, the method OnXxx raises the event named Xxx. This is also the case in a System.Web.UI.Control like Page.
If you do:
protected override void OnLoad(EventArgs e)
{
// nothing here!
}
you change the behavior of OnLoad so that it now does nothing. Therefore, most probably, no-one will ever raise ("fire") the Load event. So its event handler is never run.
If instead you do:
protected override void OnLoad(EventArgs e)
{
// maybe add some code of your own here ...
base.OnLoad(e);
// ... or here
}
then the base call will make sure the method still raises the event.
You can only raise the event explicitly, i.e. invoke the underlying delegate, if you're in the class where the event was declared. So that's not a possibility for you. The base class where Load is defined does that like this:
// inside same class where 'Load' event is defined:
protected virtual void OnLoad(EventArgs e)
{
// maybe they put some other code here ...
var loadDelegate = Load; // gets the current underlying delegate of the event
if (loadDelegate != null)
loadDelegate(this, e);
// ... or here
}
But in most situation you shouldn't override any method at all. Just add to Load when you want some code to run when the Load event fires.

Related

Is it possible to call a function on page_load event of pages that inherit from a specific Page subclass in asp.net WebFroms?

I want to execute a function on Page_load event of every System.Web.UI.Page from which derives my own CustomPage class (which obviously inherits from Page class as well)
what I have done so far it that I created CustomPage class like this:
public class CustomPage : System.Web.UI.Page
{
protected virtual void Page_Load(object sender, EventArgs e)
{
CallTOTheDesiredFunction(); //this is the call to the function I want
}
}
And in the derived Page classes I am doing this:
public class DerivedPage : CustomPage
{
protected override void Page_Load(object sender, EventArgs e)
{
base.Page_Load(sender, e);
//the rest of the page load event which executes from here on
}
}
As it is obvious, this approach is working but it is not the best solution since I have to call base.Page_Load(sender, e) on every derived page.
Is there a better solution to what I am trying to achieve?
Thank you in advance
Yes. It is better to override the Onload method rather than relying on deriving classes to call the base method.
You can still hook on the Load event in every page, but use the method in the base class.
public class CustomPage : System.Web.UI.Page
{
protected override void OnLoad(EventArgs e)
{
CallTOTheDesiredFunction(); //this is the call to the function I want
base.OnLoad(e);
}
}

How I am able to omit the parameter object sender in Handler

I am working with a Web Form in ASP.NET and I want to understand that why can I omit the parameter in override Event Handler?
This is Event :
public event EventHandler Init;
This is Delegate to Hold Data(with two parameters) :
public delegate void EventHandler(object sender, EventArgs e);
Event Handler goes like :
protected override void OnInit(EventArgs e)
{
i++;
this.Load += Page_Load;
}
Adding parameter is not allowed in above method(handler) but at the same time we are restricted to pass parameter in below case
protected void Page_Load(object sender, EventArgs e)
{
i++;
Response.Write(i);
}
Note : I have disabled my Auto Event Wire-Up attribute in Directive.
Actually you are not subscribing to Init event. AutoEventWireUp make sure Page_Init method is called when Init Event is fired.
As you have disable it, then you have to manually hook up the method like this
protected override void OnPreInit(EventArgs e)
{
Init += new EventHandler(OnInit);
base.OnPreInit(); // make sure you call this
}
Reason you will not get compile time error is because there are two types of EventHandler delegate
EventHandler(object,EvnetArgs)
EvnetHandler(EventArgs)
The difference is that Page_Load really is an event handler whereas OnInit is a method that is defined in the base class and raises the Init event. So in the case of your OnInit method, you are overriding the method and not defining an event handler.
If you want to create an event handler for the Init event, you would also have to create a method with the following signature:
protected void Page_Init(object Sender, EventArgs e)
{
// ...
}
This only works if AutoEventWireUp is set to true. Otherwise, you need to register event handlers in your ASPX page or the codebehind file. As the Init event is raised very in the page lifecycle, the event handler needs to be registered at the beginning of the request. In the special case of Init it is very common to override OnInit instead of defining an event handler. Important to note though, if you override OnInit (or one of the other On* methods) you should always call the base version in order to allow for the ASP.NET framework to do its stuff:
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// initialization code
}

how to override built in event handler in WPF c#

In my project, I want to override Touchup Event Handler which is build in the WPF. I do not know how to override this event handler for my own use. Is that possible? Someone could give some examples, I do not get some references or example about it.
You can create a custom control and override the events. refer the below code i tried for TextBox control.
class TextBoxEx : TextBox
{
protected override void OnTouchUp(System.Windows.Input.TouchEventArgs e)
{
base.OnTouchUp(e);
}
protected override void OnTouchDown(System.Windows.Input.TouchEventArgs e)
{
base.OnTouchDown(e);
}
}
It is possible.
Let's say you want to override this TouchUp event (Completely override it). You will need to define a new function to handle this. Something like :
private void Custom_TouchUp(object sender, TouchEventArgs e)
{
// Do some stuff there
}
(It may not be TouchEventArgs, I haven't tried it, but it looks like it)
Then, in your xaml, in your object definition, you need to specify to the targeted object that it should use this function. If it's a combobox (for example), you'll have something like this :
<Combobox [...] TouchUp=Custom_TouchUp>
<Eventual parameters>
</Combobox>
And voila! Your object will use your new function.
Now, let's say you just want to alter a tiny bit the current event, then you can just override the OnTouchUp function that will be called when the event occurs. Something like this should do :
public override void OnTouchUp()
{
base.OnTouchUp();
// Other stuffs
}
But then, every element of the same class will act the same. So that's really useful when you want to define a new custom class

An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module

I am regularly encountering errors of type "An unhandled exception of type 'System.StackOverflowException' occurred in Unknown Module.". This happens in a website with a quite large code base. But the error occurs only after several minutes of the website.
This is where the error pointed me to:
public partial class HealthInsurance : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
base.OnLoad(e);
Page.Header.DataBind();
}
}
You should not call the base class' implementation of OnLoad() from an autowired Page_Load() handler.
Under the hood, OnLoad() is responsible for invoking Page_Load(), so your code ends up in an infinite recursive loop.
You only have to write:
protected void Page_Load(object sender, EventArgs e)
{
Page.Header.DataBind();
}
Things would be different had you chosen to override OnLoad() rather than rely on Page_Load(). In that case, you indeed have to call the base class' method:
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Page.Header.DataBind();
}
If you are subscribing to the Load event, do not call the base OnLoad as the base OnLoad is what's responsible for firing the Load event, so it will be an endless cycle.
However, if you are overriding the OnLoad method, then it's appropriate to call the base OnLoad method, e.g.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Page.Header.DataBind();
}
In the above case, note the override keyword.

UserControl Load event not fired

I have WinForms application. My Form derived class has UserControl derived class.
I simply put several controls into one UserControl to simplify reuse. The Load event of UserControl is not fired. Do I have to set some property?
Try overriding the OnLoad() method in your UserControl. From MSDN:
The OnLoad method also allows derived
classes to handle the event without
attaching a delegate. This is the
preferred technique for handling the
event in a derived class.
protected override void OnLoad(EventArgs e)
{
//Your code to run on load goes here
// Call the base class OnLoad to ensure any delegate event handlers are still callled
base.OnLoad(e);
}
There wouldn't be any special properties you need to set for a UserControl's events to fire. You have one of 2 ways to subscribe to the event. In the Properties (property grid) select the events list...double-click at the Load property. All the necessary pieces of code will be put in place, and your cursor will be waiting for you at the proper method.
The second method is subscribing to the event like so:
public MyMainForm( )
{
InitializeComponents();
myUserControl.Load += new System.EventHandler(myUserControl_Load);
}
void myUserControl_Load(object sender, EventArgs e)
{
MessageBox.Show(((UserControl)sender).Name + " is loaded.");
}
One reason for the Load event to stop firing is when you have a parent of your control that does something like this
protected override void OnLoad(EventArgs e)
{
//do something
}
you always need to make sure to do this
protected override void OnLoad(EventArgs e)
{
//do something
base.OnLoad(e);
}

Categories

Resources