raising Page event with customs webcontrol

F

Frank

Hello,

I'm trying to raise a Page level event from a custom webcontrol. I can get
the event to fire but the context of the even is within the webcontrol and
not the Page. How can I get the event to be at the Page context level where I
can change other controls, variables, etc on the Page?
 
T

Teemu Keiski

Hi,

if you declare a public event on the control (e.g raise it from the
control). Page is capable to react to that event. E.g that happens on Page
level (Page and controls go the same request processing cycle and also are
in the somewhat spame phase when going through events related to request
processing, like On Init, Load, OnPrerender...)

For example you have

**
Public Event MyEvent As EventHandler
**
declared on control and you raise it by calling "RaiseEvent
MyEvent(Me,EventArgs.Empty)"

Page is capable to deal with it for example

**
Protected Sub MyControl_MyEvent(sender As Object, e As EventArgs) Handles
MyControl.MyEvent
....
End Sub
**
where MyControl would be the ID of your custom control.
 
F

Frank

The code in the webcontrol does call the event delegates but the code I'm
using is in C#. In fact using the method you describe results in an error
below due to the fact that the scope of the call is within the webcontrol:

HttpException (0x80004005): Response is not available in this context.]
System.Web.UI.Page.get_Response() +62
ART.Projects.Test_deptSelect(Object sender, oBarSelectEventArgs e) in
o:\inetpub\artdata\projects.aspx.cs:174
dropBarDisplay.SelectsDisplay.lstDepartments_SelectedIndexChanged(Object
sender, EventArgs e) in c:\documents and settings\administrator\my
documents\visual studio
projects\specialcontrols\dropbardisplay\obardisplay.cs:309
System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs e)
+108

System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent() +26
System.Web.UI.Page.RaiseChangedEvents() +115
System.Web.UI.Page.ProcessRequestMain() +1099

The web control is processing other web control events locally, when flagged
however the code tries to fire the event handler at the Page level through
the delegates. The problem however is primarily due to the fact that ASP.Net
events are not asynchronous as in desktop applications. This results in a
synchronous call of event methods. So what happens is the calling of the
event method from an event method within the control is actually nothing more
than a function call from within the webcontrol, so its scope remians within
the webcontrol. The eventhandler method on the page will fire and be
processed but its context scope cannot access page level elements.

The means to raise the event so it has Page level scope context can be done
through the registering of the control to raise events and place a public
RaisePostBackEvent method within the control. Within the RaisePostBackEvent
method you can call the delegates that reference the Page level eventhandlers
and they will have Page level scope context. The reason this works is due to
the fact that the call to the event delegates originates from the Page
through the call to the public RaisePostBackEvent method.


The APS.Net event model is limited in how one can raise events internally
from other dll's. There are other solutions to work around this problem but I
won't go into them here.

Note: That usercontrols do not suffer from this problem because they never
loose thier Page level scope context.
 
F

Frank

The code in the webcontrol does call the event delegates but the code I'm
using is in C#. In fact using the method you describe results in an error
below due to the fact that the scope of the call is within the webcontrol:

HttpException (0x80004005): Response is not available in this context.]
System.Web.UI.Page.get_Response() +62
ART.Projects.Test_deptSelect(Object sender, oBarSelectEventArgs e) in
o:\inetpub\artdata\projects.aspx.cs:174
dropBarDisplay.SelectsDisplay.lstDepartments_SelectedIndexChanged(Object
sender, EventArgs e) in c:\documents and settings\administrator\my
documents\visual studio
projects\specialcontrols\dropbardisplay\obardisplay.cs:309
System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs e)
+108

System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent() +26
System.Web.UI.Page.RaiseChangedEvents() +115
System.Web.UI.Page.ProcessRequestMain() +1099

The web control is processing other web control events locally, when flagged
however the code tries to fire the event handler at the Page level through
the delegates. The problem however is primarily due to the fact that ASP.Net
events are not asynchronous as in desktop applications. This results in a
synchronous call of event methods. So what happens is the calling of the
event method from an event method within the control is actually nothing more
than a function call from within the webcontrol, so its scope remians within
the webcontrol. The eventhandler method on the page will fire and be
processed but its context scope cannot access page level elements.

The means to raise the event so it has Page level scope context can be done
through the registering of the control to raise events and place a public
RaisePostBackEvent method within the control. Within the RaisePostBackEvent
method you can call the delegates that reference the Page level eventhandlers
and they will have Page level scope context. The reason this works is due to
the fact that the call to the event delegates originates from the Page
through the call to the public RaisePostBackEvent method.


The APS.Net event model is limited in how one can raise events internally
from other dll's. There are other solutions to work around this problem but I
won't go into them here.

Note: That usercontrols do not suffer from this problem because they never
loose there Page level scope context.
 
T

Teemu Keiski

Well,

Either your code runs in design mode (within IDE in designer), when there's
no associated HttpContext or you run the code on such phase when HttpContext
would not yet be associated with the Page and its controls (for example
instantiation time of Page & controls e.g constructor of these, or member
variable instantiation). Error msg is; Response not available in this
Context, which would be raised when there's no associated http context e.g
no associated request.

Second thing: inside a control you can get to the HttpContext yourself via
control's Context property and you can also access the Page in typed manner
by casting HttpContext.Current.Handler to the code-behind type of the Page
class (certainly works also via Control's Page property).

I suggest that you post some code which you have worked with, it's easier to
pinpoint the problem there.

--
Teemu Keiski
ASP.NET MVP, AspInsider
Finland, EU
http://blogs.aspadvice.com/joteke





Frank said:
The code in the webcontrol does call the event delegates but the code I'm
using is in C#. In fact using the method you describe results in an error
below due to the fact that the scope of the call is within the webcontrol:

HttpException (0x80004005): Response is not available in this context.]
System.Web.UI.Page.get_Response() +62
ART.Projects.Test_deptSelect(Object sender, oBarSelectEventArgs e) in
o:\inetpub\artdata\projects.aspx.cs:174
dropBarDisplay.SelectsDisplay.lstDepartments_SelectedIndexChanged(Object
sender, EventArgs e) in c:\documents and settings\administrator\my
documents\visual studio
projects\specialcontrols\dropbardisplay\obardisplay.cs:309
System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs
e)
+108

System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent()
+26
System.Web.UI.Page.RaiseChangedEvents() +115
System.Web.UI.Page.ProcessRequestMain() +1099

The web control is processing other web control events locally, when
flagged
however the code tries to fire the event handler at the Page level through
the delegates. The problem however is primarily due to the fact that
ASP.Net
events are not asynchronous as in desktop applications. This results in a
synchronous call of event methods. So what happens is the calling of the
event method from an event method within the control is actually nothing
more
than a function call from within the webcontrol, so its scope remians
within
the webcontrol. The eventhandler method on the page will fire and be
processed but its context scope cannot access page level elements.

The means to raise the event so it has Page level scope context can be
done
through the registering of the control to raise events and place a public
RaisePostBackEvent method within the control. Within the
RaisePostBackEvent
method you can call the delegates that reference the Page level
eventhandlers
and they will have Page level scope context. The reason this works is due
to
the fact that the call to the event delegates originates from the Page
through the call to the public RaisePostBackEvent method.


The APS.Net event model is limited in how one can raise events internally
from other dll's. There are other solutions to work around this problem
but I
won't go into them here.

Note: That usercontrols do not suffer from this problem because they never
loose there Page level scope context.


Teemu Keiski said:
Hi,

if you declare a public event on the control (e.g raise it from the
control). Page is capable to react to that event. E.g that happens on
Page
level (Page and controls go the same request processing cycle and also
are
in the somewhat spame phase when going through events related to request
processing, like On Init, Load, OnPrerender...)

For example you have

**
Public Event MyEvent As EventHandler
**
declared on control and you raise it by calling "RaiseEvent
MyEvent(Me,EventArgs.Empty)"

Page is capable to deal with it for example

**
Protected Sub MyControl_MyEvent(sender As Object, e As EventArgs) Handles
MyControl.MyEvent
....
End Sub
**
where MyControl would be the ID of your custom control.

--
Teemu Keiski
ASP.NET MVP, AspInsider
Finland, EU
http://blogs.aspadvice.com/joteke
 
F

Frank

Using the Page property of the control to access Page level elements would be
a problem. For one I would have to use FindControl to access any of the
controls of the Page and even If I do that the scope context won't allow me
to change any properties of the control. Believe me I tried it! To add to the
problems any variables of the Page would not be recognized within the
webcontrol at compile time. As far as getting the Response object I know I
can use the System.Web.HttpContext.Current to get to it. But the main reason
I should the error was to demonstrate that the scope context of the event
call is still within the webcontrol. If I call a public method of the
webcontrol that then calls the delegate event that references the Page level
event handler all controls and variables are accessible.

Here is a sample of code of the webcontrol, there is much more but I think
you'll get an idea as to what is happening:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="FullTrust"), DefaultProperty(""),
ToolboxData("<{0}:SelectsDisplay runat=server></{0}:SelectsDisplay>")]
public class SelectsDisplay : System.Web.UI.WebControls.WebControl,
IPostBackEventHandler, IPostBackDataHandler
{
private string pageName;
private string connStr;
public string diag = "";
private bool depthasfired = false;
protected System.Web.UI.WebControls.DropDownList lstProjects;
protected System.Web.UI.WebControls.DropDownList lstDepartments;
protected System.Web.UI.WebControls.DropDownList lstCompanies;
protected System.Web.UI.HtmlControls.HtmlTable BarDisplay;
protected System.Web.UI.WebControls.DropDownList lstTeams;
protected System.Web.UI.WebControls.DropDownList lstLocations;
public event oBarDropEventHandler proSelect;
public event oBarDropEventHandler deptSelect;
public event oBarDropEventHandler compSelect;
public event oBarDropEventHandler locSelect;
public event oBarDropEventHandler teamSelect;

protected override void
Render(HtmlTextWriter output)
{
BarDisplay.RenderControl(output);

}

public void InitializeComponent()
{
lstProjects = new
DropDownList();
this.Controls.Add(lstProjects);
lstDepartments = new DropDownList();
this.Controls.Add(lstDepartments);
lstCompanies = new DropDownList();
this.Controls.Add(lstCompanies);
BarDisplay = new HtmlTable();
this.Controls.Add(BarDisplay);
lstTeams = new DropDownList();
this.Controls.Add(lstTeams);
lstLocations = new DropDownList();
this.Controls.Add(lstLocations);

this.lstLocations.SelectedIndexChanged += new
System.EventHandler(this.lstLocations_SelectedIndexChanged);
this.lstCompanies.SelectedIndexChanged += new
System.EventHandler(this.lstCompanies_SelectedIndexChanged);
this.lstDepartments.SelectedIndexChanged += new
System.EventHandler(this.lstDepartments_SelectedIndexChanged);
this.lstProjects.SelectedIndexChanged += new
System.EventHandler(this.lstProjects_SelectedIndexChanged);
this.lstTeams.SelectedIndexChanged += new
System.EventHandler(this.lstTeams_SelectedIndexChanged);
this.Load += new System.EventHandler(this.loadDisplay);
}

//Local event handler in webcontrol
private void
lstLocations_SelectedIndexChanged(object sender, System.EventArgs e)
{

if(lstLocations.SelectedIndex != 0)
lstCompanies.Enabled = true;
else
lstCompanies.Enabled = false;
getCompanies();
oBarSelectEventArgs E = new
oBarSelectEventArgs(lstLocations.SelectedValue);
//fires delegate event to Page
if(locSelect != null)
locSelect(this,E);

}

}

//Custom EventArgs class
public class oBarSelectEventArgs : EventArgs
{
private string SelectedValue = "";
// Constructor.
public oBarSelectEventArgs(string selectedValue) {SelectedValue =
selectedValue;}
// Properties.
public string SelectItem{ get { return SelectedValue;}}
}


public delegate void oBarDropEventHandler(object sender,
oBarSelectEventArgs e);


Teemu Keiski said:
Well,

Either your code runs in design mode (within IDE in designer), when there's
no associated HttpContext or you run the code on such phase when HttpContext
would not yet be associated with the Page and its controls (for example
instantiation time of Page & controls e.g constructor of these, or member
variable instantiation). Error msg is; Response not available in this
Context, which would be raised when there's no associated http context e.g
no associated request.

Second thing: inside a control you can get to the HttpContext yourself via
control's Context property and you can also access the Page in typed manner
by casting HttpContext.Current.Handler to the code-behind type of the Page
class (certainly works also via Control's Page property).

I suggest that you post some code which you have worked with, it's easier to
pinpoint the problem there.

--
Teemu Keiski
ASP.NET MVP, AspInsider
Finland, EU
http://blogs.aspadvice.com/joteke





Frank said:
The code in the webcontrol does call the event delegates but the code I'm
using is in C#. In fact using the method you describe results in an error
below due to the fact that the scope of the call is within the webcontrol:

HttpException (0x80004005): Response is not available in this context.]
System.Web.UI.Page.get_Response() +62
ART.Projects.Test_deptSelect(Object sender, oBarSelectEventArgs e) in
o:\inetpub\artdata\projects.aspx.cs:174
dropBarDisplay.SelectsDisplay.lstDepartments_SelectedIndexChanged(Object
sender, EventArgs e) in c:\documents and settings\administrator\my
documents\visual studio
projects\specialcontrols\dropbardisplay\obardisplay.cs:309
System.Web.UI.WebControls.ListControl.OnSelectedIndexChanged(EventArgs
e)
+108

System.Web.UI.WebControls.DropDownList.System.Web.UI.IPostBackDataHandler.RaisePostDataChangedEvent()
+26
System.Web.UI.Page.RaiseChangedEvents() +115
System.Web.UI.Page.ProcessRequestMain() +1099

The web control is processing other web control events locally, when
flagged
however the code tries to fire the event handler at the Page level through
the delegates. The problem however is primarily due to the fact that
ASP.Net
events are not asynchronous as in desktop applications. This results in a
synchronous call of event methods. So what happens is the calling of the
event method from an event method within the control is actually nothing
more
than a function call from within the webcontrol, so its scope remians
within
the webcontrol. The eventhandler method on the page will fire and be
processed but its context scope cannot access page level elements.

The means to raise the event so it has Page level scope context can be
done
through the registering of the control to raise events and place a public
RaisePostBackEvent method within the control. Within the
RaisePostBackEvent
method you can call the delegates that reference the Page level
eventhandlers
and they will have Page level scope context. The reason this works is due
to
the fact that the call to the event delegates originates from the Page
through the call to the public RaisePostBackEvent method.


The APS.Net event model is limited in how one can raise events internally
from other dll's. There are other solutions to work around this problem
but I
won't go into them here.

Note: That usercontrols do not suffer from this problem because they never
loose there Page level scope context.


Teemu Keiski said:
Hi,

if you declare a public event on the control (e.g raise it from the
control). Page is capable to react to that event. E.g that happens on
Page
level (Page and controls go the same request processing cycle and also
are
in the somewhat spame phase when going through events related to request
processing, like On Init, Load, OnPrerender...)

For example you have

**
Public Event MyEvent As EventHandler
**
declared on control and you raise it by calling "RaiseEvent
MyEvent(Me,EventArgs.Empty)"

Page is capable to deal with it for example

**
Protected Sub MyControl_MyEvent(sender As Object, e As EventArgs) Handles
MyControl.MyEvent
....
End Sub
**
where MyControl would be the ID of your custom control.

--
Teemu Keiski
ASP.NET MVP, AspInsider
Finland, EU
http://blogs.aspadvice.com/joteke


Hello,

I'm trying to raise a Page level event from a custom webcontrol. I can
get
the event to fire but the context of the even is within the webcontrol
and
not the Page. How can I get the event to be at the Page context level
where I
can change other controls, variables, etc on the Page?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,534
Members
45,007
Latest member
OrderFitnessKetoCapsules

Latest Threads

Top