Custom server control: specifying event declaratively on ASPX code - asp.net

I'm currently working on several custom ASPX server controls. Of course these controls do also expose events. Now one possibility is to register a handler in the code, more specifically in the page where the custom server control resides...like
protected void Page_Load(object sender, EventArgs e)
{
myCustomControl.Click += new ....
}
But how do I have to expose the event in my server control code s.t. I can declare these event handlers directly on the ASPX code (from the Property Editor), similar as you can do it on the Button's click event??
Thanks a lot,
Juri

You do just that...
If you have a public event on your ASCX Control called PropertyChanged
then it'll be available declaritively on your Control as OnPropertyChanged
<ctl:MyControl ID="abc" runat="server" OnPropertyChanged="abc_PropertyChanged" />

Have you tried just making them public events?

This MSDN article does a good job explaining how to do this unfortunately it is more complicated than it seems like it should be.
[1]: http://msdn.microsoft.com/en-us/library/aa719907(VS.71).aspx/".NET Framework Developer's Guide"

Related

When I serve an ASP.NET page, can I render the various controls on the page in parallel?

When I serve an ASP.NET page, can I render the various controls on the page in parallel?
I have a few Telerik controls (RadGrids) on the page and when I step through the page being loaded, it seems as though the controls are databound and rendered serially.
Maybe this behavior is because I am hooked in with the debugger.
Is there anyway to load the page and have select controls build on separate threads? Is that even conceptually possible or must it be done sequentially?
You have a couple of options. You could use the ASP.NET asynchronous page model. The idea would be that you load the data for each control asynchronously and then bind that data to each control as it is retrieved.
It would look something like this:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsAsync) {
dataSource.GetDataCompleted +=
new GetDataCompletedEventHandler(GetDataCompleted);
dataSource.GetDataAsync();
}
else {
_yourCtl.DataSource = dataSource.GetData();
_yourCtl.DataBind();
}
}
void GetDataCompleted(object sender, GetDataCompletedEventArgs e) {
_yourCtl.DataSource = e.Result;
_yourCtl.DataBind();
}
You would do the same for each control on the page. The end result is that the time to render the page will equal the time to render the slowest-rendering control.
An alternative method would be to use AJAX to load the controls. I'm not familiar with the Telerik RadGrid control, but I would assume that it supports AJAX. Here's a link to a Telerik demo page that shows how to perform programatic client-side binding of a Telerik grid: http://demos.telerik.com/aspnet-ajax/grid/examples/client/databinding/defaultcs.aspx.
Take a look at this article I hope it gives you the right direction:
http://www.codeproject.com/Articles/38501/Multi-Threading-in-ASP-NET.aspx

Page_Load or Page_Init

Let's take a really simple example on using jQuery to ajaxify our page...
$.load("getOrders.aspx", {limit: 25}, function(data) {
// info as JSON is available in the data variable
});
and in the ASP.NET (HTML part) page (only one line)
<%# Page Language="C#" AutoEventWireup="true"
CodeFile="getOrders.aspx.cs" Inherits="getOrders" %>
and in the ASP.NET (Code Behind) page
public partial class getOrders : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string lmt = Request["limit"];
List<Orders> ords = dll.GetOrders(limit);
WriteOutput( Newtonsoft.Json.JsonConvert.SerializeObject(ords) );
}
private void WriteOutput(string s)
{
Response.Clear();
Response.Write(s);
Response.Flush();
Response.End();
}
}
my question is
Should it be
protected void Page_Load(object sender, EventArgs e)
or
protected void Page_Init(object sender, EventArgs e)
So we can save some milliseconds as we don't actually need to process the events for the page, or will Page_Init lack of some sorting of a method by the time it is called?
P.S. Currently works fine in both methods, but I just want to understand the ins and outs of choosing one method over the other
Basic page life cycle will answer your question Full article : http://www.codeproject.com/KB/aspnet/ASPDOTNETPageLifecycle.aspx
check same question answer : Page.Request behaviour
Either one would work, because you're essentially throwing out the page lifecycle by calling response.Clear() and response.End(). Technically you could even go as far as putting that code in prerender and it would work. By accessing the Response object you're basically going over the head of the page and cutting it off mid-stride so that you can perform a much simpler task.
I assume you simply do not want the page lifecycle at all and simply want to return JSON from this page? If so, I highly recommend implementing it as a Generic Handler (ashx). In this case you'd simply use context.Request["limit"] and context.Response.Write in your Process method. The benefit of doing this is that you don't have all the overheads of .NET preparing the page class and starting the page lifecycle, and are instead using a file intended for the task you're doing.
It is nice to understand the page lifecycle, as shown in other answers, but realistically you're not using it at all and you'd be better off moving away from the page class entirely.
Page life-cycle only has meanings in context of page elements (controls), so i don't see any differences in your case, since you don't have any other child controls in your page - this is totally irrelevant.
But here is the real question: if you don't have any rendering of html in your page (only data serialization), why you have choose to work with regular .aspx page?
Web service is ideal candidate for this scenario. And you'll be surprised how much performance improvement you'll gain in the end.
You can very well use the Page Init method. But if you have controls in your page and want to access any property of those controls then better to use the Page load event, but in your case you don't need to use page load event.
You can go through the Asp.Net Page Life cycle here to better understand which event to use.

Converting ASP.Net Web Form to User Control OnPreInit event

I'm in the process of converting an ASP.Net webform into a User control and there an event that now says
no suitable method found to override
the event code causing the compile error
protected override void OnPreInit(EventArgs e)
{
//do some stuff
base.OnPreInit(e);
}
Is there any equivalent for a user control?
The OnInit override is available. The User Control Lifecycle on MSDN should help you in determining which event to correctly override. In any case what are you trying to achieve?
No. You'll have to use Init. I cannot think of anything I've ever done in PreInit that couldn't be done in Init just as well.
http://msdn.microsoft.com/en-us/library/system.web.ui.usercontrol_events.aspx

LoadControl vs Construct ASP.Net Control

I have a question why we can only add dynamic control using LoadControl.
For example:
public partial class wucReportParam : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
wucDate() ctrl = new wucDate();
pnl.Controls.Add(ctrl);
}
}
When in the page_load method of wucDate, the child control of wucDate is null but when i use the following method:
public partial class wucReportParam : System.Web.UI.UserControl
{
public Report Report;
protected void Page_Load(object sender, EventArgs e)
{
ctrl = (wucDate)LoadControl(#"Reports\wucDate.ascx");
pnl.Controls.Add(ctrl);
}
}
In the page_load method of wucDate, the child control of wucDate is not null.
Is anyone could explain to me why asp .net don't create any child control of wucDate when i using contructor ??? Thank you
When dynamically loading a user control, it is important to ensure that the standard ASP.NET page event pipeline is initiated and progresses normally. When you use the new operator to create an instance of a user control, that user control is not properly added to ASP.NET's event system. If the events (Init, Load, PreRender, etc.) to not fire, then your control will never function properly. That is why it is necessary to use LoadControl, as that will make sure that the instance of your user control is created properly and attached to ASP.NET.
Apparently, using LoadControl with typeof (or GetType) has the same problem as using 'new' where the child controls are not initialized. Using LoadControl with a string to the ASCX file works.
Does not initialize child controls.
LoadControl(typeof(MyReport), null);
Works!
LoadControl("Report.ascx");
The initialization of the controls inside a User Control is driven by the ASCX file. Using only "new SomeControl" will not cause this initialization to run, and even if it did, all the design (markup) in the ascx file would be lost.
Remember that the class "wucDate" is only the base class which the full user control inherits from. It's not the same class as you'll get when using LoadControl("wucDate.ascx").
And to be honest, LoadControl has not much, if anything, to do with the page life cycle. That part is handled when you add the control to the container's Controls collection.
As I recall, it pertains to how ASP.NET constructs page components at run time. In ASP.NET although your pages have a class which is defined in your code-behind file, their types don't truly exist until run time. Like a page, although you have a control defined the wucDate type isn't created until it is included at run time. For this reason, the control must be loaded with LoadControl in order to both initialize the type and properly run in through the page life cycle.
This is to the best of my memory so if I'm incorrect here please let me know.

How come the attributes for event handler properties on ASP.NET controls have a prefix (OnLoad for the Load event handler)

This is just for a better understanding of the ASP.NET framework. When you use a control in a declarative way (that would be web form markup), you assign event handlers by their method name using an attribute that starts with On:
<asp:Button runat="server" OnClick="..."/>
But when you look at the System.Web.UI.WebControls.Button class it has an EventHandler property named Click that the delegate is assigned to:
button.Click += new EventHandler(...);
So how is this implemented? Is that just a convention followed by the parser?
I know, it's a strange question, the answer will do nothing but satisfy my curiosity.
This is a naming convention used by ASP.NET which, rather unhelpfully, looks identical to another common naming convention widely used throughout .NET. Despite the apparent similarity, these two conventions are unrelated.
The .NET-wide convention, which turns out to be irrelevant here, is that it's common for events to have corresponding methods that raise the event, and for those methods' names to be formed by adding an On prefix to the event name. For example, the Click event offered by Button is related to an OnClick method, which raises that event (as has already been stated in another answer here).
The confusing part is that the OnClick method has nothing to do with the OnClick attribute that the question concerns.
It's easy to demonstrate that the OnSomeEvent methods are irrelevant here by writing a control that doesn't have any such method. Here's the codebehind for a simple user control:
public partial class EventWithoutMethod : System.Web.UI.UserControl
{
public event EventHandler Foobar;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
if (Foobar != null)
{
Foobar(this, EventArgs.Empty);
}
}
}
This declares a Foobar event. (It never actually raises it, but that doesn't matter for the purposes of exploration.) It does not define an OnFoobar method. Nevertheless, ASP.NET is perfectly happy for us to use the OnSomeEvent convention when we use the control:
<user:EventWithoutMethod runat="server" OnFoobar="FooHandler" />
In fact, it's not only happy for us to do that, it actually requires it. Even though my control doesn't define any member called OnFoobar—the event is called just Foobar—I have to write OnFoobar if I want to attach the event handler from my .aspx file. If I just put a Foobar attribute in there in an attempt to attach the event, the handler will never run. (Unhelpfully, ASP.NET doesn't generate an error when you do that, it just silently fails to do anything with the attribute, and the event handler never runs.)

Resources