what are the pros and cons of using a standard event handler or overriding the base class of an asp.net page? Are there any? I've seen both used to do the same thing.
protected void Page_PreInit(object sender, EventArgs e)
{
//Put your code here
}
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
//Put your code here
}
if you use the override you can decide when the custom function should be execute. after or before base method. but if you use auto wireup events it will execute after the base event.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
//Put your code here
}
or
protected override void OnPreInit(EventArgs e)
{
//Put your code here
base.OnPreInit(e);
}
First of all, both aren't the same thing.
OnLoad, OnInit and so on are the methods which fires events. Its goal is encapsulating event firing so, if these're virtual methods, derived classes will have the ability of override them and do something before and/or after firing some event.
I wouldn't ask for pros and cons, but "when to use them", because both are different things.
When to use event firing methods
Some operation must be executed before or after some page or control life-cycle.
Some life-cycle step needs to initialize something so page or control subscribers will do something in its correct state by definition.
Authorization: that's preventing the execution of some resources during life-cycle because of security issues.
Add some custom life-cycle step, so page or control needs to notify some subscribers about that.
When to use events directly
Page or control itself, or an associated to control collection or just an observer, needs to do something when page or control is in some life-cycle step.
Pay attention because if you tend to override event firing methods you're modifying the way events are fired themselves, which is a critical thing.
If you need to do something during some page or control life cycle, subscribe to the event, and if you need to subscribe to do something before some event is fired, implement a new event and fire it before next one gets raised:
public event EventHandler CustomEvent;
protected virtual void OnCustomEvent(EventArgs e)
{
if(CustomEvent != null)
{
CustomEvent(this, e);
}
}
protected override void OnPreRender(EventArgs e)
{
OnCustomEvent(new EventArgs());
base.OnPreRender(e);
}
In my opinion, overriding the way an event gets fired when the situation is some object needs to be notified when something happens is a bad usage of C# language, since this is achieved by using event delegation model.
There is much difference in both of the name that you have mentioned, I would like to tell you about that, actually overriding means to use the same method with the same name in the child class, but only the parameters are different in both of the methods, If suppose take the example of the calculating the area, and if you want to calculate the area of two to three different object, then you have to take three different names rather you can use the same name for each, just the different parameters.
Page_PreInit will be called if autoeventWireUp is On.
The func OnPreInit is virtual , and in your page is overrided.
but the master function which is virtual - is executing the code which triggers the Page_PreInit.
so you have to call base.OnPreInit(e); even if you override it.
IF YOU NEED TO PUT SOME CODE BEFORE OR AFTER THE OnPreInit so use the second one .
Related
I'm only a beginner so ,my question might sound a bit stupid or basic.
I learn programming in asp.net, therefore I see a lot of functions activated by events. Yet, I didn't find anything in the code nor in the type signature that defines which event activates the function.
So, in functions like public void Page_Load (object sender, EventArgs e), where are the code lines that determine what event will make the function to start? Does it have any relation to the function's name?
Thanks :)
Functions like Page_Load are called by ASP.NET in a particular order. You cannot configure which will fire first. The idea is that you override the ones you need to fire your code in the particular order you need.
Here is the MSDN Page Lifecycle information which talks about which event can be overridden and what order they go in.
In ASP.Net 1.1, we used to have the following system generated code in every code behind files.
public class Default : System.Web.UI.Page
{
// ----- System generated code
protected System.Web.UI.WebControls.TextBox Name;
protected System.Web.UI.WebControls.TextBox Email;
public Default()
{
Page.Init += new System.EventHandler(Page_Init);
}
// ----- System generated code
private void Page_Init(object sender, System.EventArgs e)
{
}
}
It basically registers method to page event. They are nothing but just make the code behind file dirty.
Start from ASP.Net 2, they moved the system generated code to designer file, and code behind file becomes clean and easy read.
public class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, System.EventArgs e)
{
}
-- OR --
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
}
}
where are the code lines that determine what event will make the
function to start?
ASP.Net uses conversion over configuration approach to register events. It means, you can name a Protected method with following event name, and the page will know how to attach those event. For example, Page_Init, Page_Load and Page_PreRender
In addition, you can override those events explicit if you want.
https://msdn.microsoft.com/en-us/library/ms178472.aspx
I need to change a certain DataGridView's property (a DataSourceUpdateMode for one of its binding) only when ALL of its initial data bindings are completed.
I tried subscribing to the "DataBindingComplete" event, but it's fired too many times (one or more time for each binding associated to the control); what I need is a more global "AllDataBindingsComplete" event, fired when the control is ready to be displayed to the user.
As a temporary workaround, I'm using the MouseDown event (I've assumed that when the user is able to click the control, it means that the control is displayed... :) and the events I'm playing with - SelectionChanged - are fired after the MouseDown):
protected override void OnMouseDown(MouseEventArgs e)
{
Binding selectedItemsBinding = this.DataBindings["SelectedItems"];
if (selectedItemsBinding != null)
{
selectedItemsBinding.DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
}
base.OnMouseDown(e);
}
It works, but it smells like an ugly hack A LOT (and it's called too many times, only one time is enough for my needs).
Is there a better way?
(yes, I'm trying to adopt MVVM in a Windows Forms project, and I've added a bindable "SelectedItems" property to the DataGridView...)
What I've done at the Windows Forms form level, and may be improvised down to just the control(s) you want, is to subclass the Windows Forms baseclass into my own. Then, in its constructor, attach an extra event call to the Load() event.
So when everything else is completely loaded, only THEN will it hit my custom method (of the subclass). Since it is the bottom of the call-stack chain being attached to the event queue, I know it's last and everything else is done... Here's a snippet of the concept.
public class MyForm : Form
{
public MyForm()
{
this.Load += AfterEverythingElseLoaded;
}
private void AfterEverythingElseLoaded(object sender, EventArgs e)
{
// Do my own things here...
}
}
This concept can be applied to the Init() function too if that's more appropriate for your control... Let everything else within it get initialized(), then do you the "AfterInitialized()" function.
I am trying to wrap my head around some WPF specific stuff, and have yet to find the concrete relation between the UIElement.AddHandler method and the EventManager.RegisterClassHandler method.
I have googled a bit and found this interesting MSDN article:
http://msdn.microsoft.com/en-us/library/ms747183.aspx
Here it states:
"Routed events consider two different types of listeners to the event: class listeners and instance listeners. Class listeners exist because types have called a particular EventManager API, RegisterClassHandler, in their static constructor, or have overridden a class handler virtual method from an element base class. Instance listeners are particular class instances/elements where one or more handlers have been attached for that routed event by a call to AddHandler."
Alright now so I know the difference between a class and its instance, but somehow I cannot make sense out of this specific part of the document.
Can anyone clear that up for me?
I don't know, what exactly do you want to know. Things are pretty simple: you can register handler at instance (object) level, or at class level.
The difference is, when you register event at class level, it will get called first, before any instance level handlers (of course tunneling or bubbling still takes place before, if handling class is lower/higher in logical tree). So you can handle this event at class level and filter whether this event should be handled by instance or not (by setting e.Handled = true you will stop event for going through other handlers). It may be useful in some cases, but for now I have no example in my mind to share.
This sample will register event handler that will be called only when event was raised for specific instance of element:
DockPanel panel = new DockPanel();
panel.AddHandler(Button.ClickEvent, new RoutedEventHandler(Button_Click));
And this will create event handler, that will be called each time any DockPanel will get Button.Click event, before instance handler of this DockPanel will get called:
EventManager.RegisterClassHandler(typeof(DockPanel),
Button.ClickEvent, new RoutedEventHandler(ButtonClass_Click));
If methods were:
private void ButtonClass_Click(object sender, RoutedEventArgs e)
{
Debug.Write("Class level handler");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Debug.Write("Instance level handler");
}
This would create output:
Class level handler
Instance level handler
But if in class level handler you would set event args to handeled (e.Handled = true;), it would filter out this event for instance level handler (and bubbling up in logical tree).
I want to redirect to a page without performing any task on the present page. I think it would be good, if I redirect without loading any control on the page. So I need an event, where controls have not been initialized yet.
I think you might be looking for PreInit event, Please have a look at
Life-Cycle Events
You might try one of the application-level events in Global.asax - for example Application_BeginRequest. Something like
void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Url.AbsolutePath.Contains(...))
{
Response.Redirect("SomePage.aspx");
}
}
What is the proper way to fire an ASP.NET control event programatically?
I am looking to refactor a little code and I see items sprinkled in the code behind coded like this; the developer is calling the event handler and saturating it with params.
for a DropDownList
ddlAddress.SelectedIndex = 1;
ddlAddress_SelectedIndexChanged(null, new EventArgs());
&
for a RadioButtonList
rblAction.SelectedIndex = 0;
rblActionType_SelectedIndexChanged(null, new EventArgs());
Is this normal coding practice? What should I do as to not disrupt/break the page?
Any thoughts or suggestions would be appreciated.
Thanks,
~ck in San Diego
I would start by removing all of the code from the actual event's method and refactor it into a new method called AddressChanged or whatever else fits your naming standards. You can then call that new function from anywhere else in your code.
protected void ddlAddress_SelectedIndexChanged(object sender, EventArgs e){
AddressChanged();
}
private void AddressChanged(){
//do the changed event
}
private void doingSomething(){
ddlAddress.SelectedIndex = 1;
AddressChanged();
}
Note that you're calling the event handler programatically, not the event.
This can be indicative of a design problem, because usually event handlers should not be relying on each other to execute in a specific order. However, I have seen this pattern and even used it occasionally when code that existed in one event handler needed to be executed in another event handler and could not be refactored at that time. You can set the "sender" to indicate that it's coming from elsewhere in the code and not from the expected control itself, but this is a little bit too opaque to be called a good design.
It would be better practice to refactor out the code that needed to be shared, and put it in a private method, and have both event handlers use it, passing in whatever data from the sender or the eventargs that it needed.