When I've built applications in the past I've used AutoEventWireup to handle the page events for me. From what I've read this incurs a significant performance cost and I'd like to do it manually in my current application.
What is the correct place to set up the event handlers?
My initial thought was to just set up a constructor in my code behind file and do it there but I'm assuming that the auto generated portion of the partial class already contains a constructor that I'd be overriding.
I'm sorry to ask here on such a simple question. It seems like this should be easily searchable but I'm just not finding the answer I need. Thanks in advance for the help.
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
Load += new EventHandler(Page_Load);
}
For controls it's OnInit, since they have no OnPreInit. To be honest I've used OnInit for pages as well in the past :)
Of course, you could just do the above for all the events you need for your page, and define no event handlers whatsoever.
Related
I programming a WPF GUI that uses multiple Views. I am using the MVVM Light Toolkit to implement the MVVM pattern.
For Navigating i use this mechanism by changing my main frame to a NavigationWindow and all my views to Pages.
I injected the navigation service in the ViewModel constructor and now I can navigate between the views.
However, i would like to transmit data between the views while navigating. There is a method from Navigation Window that makes this possible through event handlers. I already implemented a method into my Interface but I'm having problems calling the event handler on the navigated View Model.
Can anyone tell me how to call the event handler inside my ViewModel?
Thanks!!
Edit: I tried calling:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
}
But i get an error saying:
OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs)': no
suitable method found to override
I already cleaned my solution and tried a rebuild...
Any ideas?
Edit2:
So i found out that in WPF .Net 4.5 the OnNavigatedTo event is gone. What i couldnt find out why and how i could call something similiar.
I haven't gotten an answer to my question so I will attempt an answer...
Don't over think this...if one needs to transfer information either create a static link to the VM(s) in question, or set aside a static drop on the app class. Either way when a view is shown, subscribe to one of the initialization/load events and pick up the information at the predetermined location.
I have a WinForm app, the form has TabControl, control has three tabs tabPage1,tabPage2,tabPage3.
The Tab 'tabPage3' is hosting a User defined control which internally has one or more child controls.
Now my problem lies in tabPage3,
I know it is a pure Winforms behavior, until your parent is not activated child controls Onload event won't fire.
I have a requirement to force the Onload event to fire when the focus is on tabPage1, tabPage2. Is there any way to force the Onload event to fire.
I have already visited following links but didn't find any clue. Link Link Link
This is a very unusual requirement, strongly smells like an XY problem. The Load event is heavily over-used in Winforms, a side-effect of it being the default event for a Form or UserControl. One of the behaviors inherited from VB6, the Load event was a big deal in that language. What you want can easily be accomplished by not giving Winforms a choice:
public UserControl3() {
InitializeComponent();
CreateHandle();
}
The CreateHandle() call does the forcing, OnLoad will immediately run. But do be aware that this happens very early, too early to do the kind of things that you'd really want to use OnLoad() or the Load event for. Which are rather limited, it is only truly necessary to discover the actual Location and Size of the control. Anything else belongs in the constructor. Surely including the code that you now run in OnLoad().
Strongly favor using the constructor instead.
I had a similar problem for a previous project, for my needs I managed to just iterate over every tab page in the forms constructor (or possibly OnLoad I can't remember) and then reset the index back to 0 before ever showing the end user.
Something similar to:
for(int i = 1; i < tabControl.TabCount; i++)
tabControl.SelectTab(i);
tabControl.SelectTab(0);
There's loads of posts on this subject on the net, but I cant find one that fits my situation;
I've have a BasePage class, which my .aspx inherit from; I also have BaseLabel & BaseDDL classes, which extend Label & Dropdownlist respectively. On top of this I have a ReadyDDL class, which combines BaseLabel & BaseDDL into a single control (but this is a class, not a user control) and renders them with their own Div, Table, TableRow, TableCells, & another Label. The ReadyDDL class enables me to define label & dropdownlist & layout in a single html statement as per:
<moc:ReadyDDL ID="Person" runat="server" Member="#UserID" Caption="Create strike for"
DataSourceSQL="SELECT ID, UserName FROM [User] WHERE isDeleted = 0 AND ClientID = 3" TextField="UserName" ValueField="ID"
OnSelectedIndexChanged="ddl_SelectedIndexChanged" />
However I have a problem or two:
a) The event doesnt fire. The posts I have read on this subject say that the dropdown must be recreated OnInit & all will be fine. BUT -
I'm not dynamically creating a dropdownlist, but a custom extension of one - thus the code which creates the dropdownlist isnt in my aspx, where the event handler is defined, but is in a separate .cs file and accordingly, I cannot write
ddl.SelectedIndexChanged += new EventHandler(X);
because X doesnt exist in the class, only the page.
The only way I've found to get around this is to expose a string property (OnSelectedIndexChanged) which sets another property in BaseDDL, and when BaseDDL is rendered, to add the OnSelectedIndexChanged property to the markup produced.
The html produced looks ok, and on screen it looks ok, and it does postback when I change the selection in the control, but the eventhandler doesnt fire: it currently just contains a couple of assignment statements, which I have a breakpoint on, and which isnt reached.
On reflection, I suppose, rendering the handler only adds the event to the control in so far as the client is concerned, and the server doesnt know about it - but how can I overcome this, and define the handler at control initialisation, when the handler isnt in the same source code file as the initialisation code?
Does anyone have any ideas on either (1) getting the event to fire, or (2) how I can define the event in code, rather than via rendering?
Any questions please ask. Any help or suggestions will be appreciated, and I will mark Q as answered if suitable information comes.
b) the selected value is lost on postback. I know I have to do something with Viewstate, but I havent figured out just what, yet. If you know how I can implement a solution to this, a short example would be much appreciated.
Appears that your are developing a composite control - the correct way to go about this is to inherit from CompositeControl class and override CreateChildControls to add your child controls. This method is called by ASP.NET early in life-cycle and that would eliminate your view-state related issues.
See this article for developing composite control. For event, string typed property is not going to work - you must define the event at your composite control level. You can bubble up the child's event by raising your own event in the handler (this is shown in the article). Another way would be short-circuit the event handlers. For example, define the event in your composite control such as
public event EventHandler SelectedIndexChanged
{
add
{
childDdl.SelectedIndexChanged += value;
}
remove
{
childDdl.SelectedIndexChanged -= value;
}
}
childDll is reference to your child ddl control.
I'm working on an ASP.NET project in which the vast majority of the forms are generated dynamically at run time (form definitions are stored in a DB for customizability). Therefore, I have to dynamically create and add my controls to the Page every time OnLoad fires, regardless of IsPostBack. This has been working just fine and .NET takes care of managing ViewState for these controls.
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
RenderDynamicControls()
}
private void RenderDynamicControls()
{
//1. call service layer to retrieve form definition
//2. create and add controls to page container
}
I have a new requirement in which if a user clicks on a given button (this button is created at design time) the page should be re-rendered in a slightly different way. So in addition to the code that executes in OnLoad (i.e. RenderDynamicControls()), I have this code:
protected void MyButton_Click(object sender, EventArgs e)
{
RenderDynamicControlsALittleDifferently()
}
private void RenderDynamicControlsALittleDifferently()
{
//1. clear all controls from the page container added in RenderDynamicControls()
//2. call service layer to retrieve form definition
//3. create and add controls to page container
}
My question is, is this really the only way to accomplish what I'm after? It seems beyond hacky to effectively render the form twice simply to respond to a button click. I gather from my research that this is simply how the page-lifecycle works in ASP.NET: Namely, that OnLoad must fire on every Postback before child events are invoked. Still, it's worthwhile to check with the SO community before having to drink the kool-aid.
On a related note, once I get this feature completed, I'm planning on throwing an UpdatePanel on the page to perform the page updates via Ajax. Any code/advice that make that transition easier would be much appreciated.
From Dirk to Dirk :-)
What do you mean with RenderDynamicControls? Create and set controls? If this is your intention not ASP.NET is managing your ViewState, but you do. If you fill the controls on every load, you always overwrite the existing ViewState!
If you want to use the ViewState, create your controls in the pages init event and fill them in the load event, but only if the request isn’t a postback. This is necessary, because ASP.NET recreates the ViewState between init and load. And this is also the reason for the two “rendering cycles” you describe. You need the first control creation cycle because ASP.NET can’t restore the ViewState without a proper control set and ASP.NET can’t react proper on your response without it.
Back to your code: In general your RenderDynamicControlsALittleDifferently wouldn’t work - because you create your controls too late in the pages life cycle and you would damage the ViewState by inserting new objects to the control collection. In a similar situation I solved this problem by a redirecting the page to itself (Response.Redirect). In this case RenderDynamicControls would do the job, based on a “little differently situation” after you change your internal state.
I want to create my own naming convention for page events rather than AutoEventWireUp but I couldn't find Component Initialize methods any where ? Should I override it ? But in which class it is defined ?
Thanks...
Edit :
For example : I don't want to use Page_Load but LoadThisPage naming. So It should be like
Load += new LoadThisPage(sender,e);
I was expecting a InitializeComponent method where I can initialize page,controls etc. events handlers...But it turned out to be Constructor function :)
So what confused me is I thought there should have been a method like InitializeComponent which does things for me already created by Designer itself so I thought I could define my own event handler names within this method by overriding it in the say Default.aspx.cs .
But the answer was simple :) Thanks...
Your question isn't really clear as to what you're trying to do.
Page events are defined in the System.Web.UI.Page class, some of which are inherited from System.Web.UI.Control. You don't need to use AutoEventWireUp if you don't want to, and you're free to override all of the Page methods that would normally raise the lifecycle events (OnInit, OnLoad, OnPreRender, etc.) and then not call the base methods, effectively squelching the events from being raised.
You can see some limited discussion around this on this blog post.
As Hogan noted, this sounds like a bad idea. Could you expand on what you're trying to accomplish?
This sounds like a bad idea to me.
However, you should be able to find auto-created code by selecting the project display options, I believe it is right click in project explorer, and selecting display hidden files or display all files. Then you will see additional .vb files created by the system. You might also have click on the little plus sign.
additonal added notes
Most of the events (btw) are defined in the base class(es) in System.Web.UI.Page and not in the code created for a specific instance.