Page and Control Event Sequence

  • Thread starter Thread starter Jordan S.
  • Start date Start date
J

Jordan S.

I'm just wondering if this would work. Please note that I'm not asking *how*
to raise events. I'm clear on that. What I'm not clear on is the sequence in
which events are raised by custom controls relative to the hosting Page, and
therefore if the following specific arrangement would even work.

What I'm looking to do is dynamically insert multiple custom composite Web
server controls onto a blank Page. This is no problem, I know how to do this
part.

What I need is for one of these controls to "broadcast" events of interest
to any other controls on the hosting Page that may be interested. But I do
not want for any of the controls on the page to directly know anything about
each other (hold references to each other).

So, to make this happen I am thinking that this would work:
A control gets notified - via the hosting Page - of the event originating
in another control.

Specifically:

1. During PostBack, control #1 raises an event (that is of interest to
Control #2).

2. The hosting Page is subscribed to the event in Control #1

3. The hosting page then raises an event of its own, passing along the
EventArgs received from Control #1.

4. Control #2 is subscribed to the Page's event [that is raised in step 3
above], and consequently receives notification (from the Page) that includes
a copy of the EventArgs-derived class sent from Control #1.

Will this work? Will ASP.NET, during PostBack, raise the events in the
correct sequence? (Control riases event ----- page raises another
vent ----- Control handles event raised by Page)

Thanks!
 
Hi,

I think it should work. Only downside with this approach is that you need
"tighter" coupling between the page and the control (e.g the control that's
listening for page's passthrough event needs to know more about the type of
the page, in practise some sort of interface etc)

Here's a sample

//INTERFACE - page implements

using System;

public interface IClickEventPage
{
event EventHandler Click;
}

//UC1 - raises an event

<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="WebUserControl1.ascx.cs"
Inherits="WebApplication2.WebUserControl1" %>
<asp:Button ID="Button1" runat="server"
Text="Clicking on this will raise UC's click event"
onclick="Button1_Click" />

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
public partial class WebUserControl1 : System.Web.UI.UserControl
{
private static readonly Object EventClick = new Object();

public event EventHandler Click
{
add
{
Events.AddHandler(EventClick, value);
}
remove
{
Events.RemoveHandler(EventClick, value);
}
}
protected void Page_Load(object sender, EventArgs e)
{

}

protected void Button1_Click(object sender, EventArgs e)
{
EventHandler h = Events[EventClick] as EventHandler;
if (h != null)
h(this, EventArgs.Empty);
}
}
}


//UC2 - listens for page's event
<%@ Control Language="C#" AutoEventWireup="true"
CodeBehind="WebUserControl2.ascx.cs"
Inherits="WebApplication2.WebUserControl2" %>
<asp:Label ID="lblInfo" runat="server" />

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{
public partial class WebUserControl2 : System.Web.UI.UserControl
{
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
IClickEventPage p = Page as IClickEventPage;
if(p != null)
{
p.Click += new EventHandler(p_Click);
}

}

void p_Click(object sender, EventArgs e)
{
lblInfo.Text = "Something occurred, informed by the Page:" +
DateTime.Now.ToString();
}
protected void Page_Load(object sender, EventArgs e)
{

}
}
}

//PAGE - acts as middle-man

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
Inherits="WebApplication2._Default" %>

<%@ Register src="WebUserControl1.ascx" tagname="WebUserControl1"
tagprefix="uc1" %>

<%@ Register src="WebUserControl2.ascx" tagname="WebUserControl2"
tagprefix="uc2" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>

<uc1:WebUserControl1 ID="USerControl1" runat="server"
OnClick="UserControl1_Click" />

</div>
<uc2:WebUserControl2 ID="WebUserControl21" runat="server" />
</form>
</body>
</html>


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication2
{

public partial class _Default : System.Web.UI.Page, IClickEventPage
{
protected void Page_Load(object sender, EventArgs e)
{

}

protected void UserControl1_Click(object sender, EventArgs e)
{
EventHandler click = Events[EventClick] as EventHandler;
if (click != null)
click(this, e);

}

#region IClickEventPage Members

private static readonly Object EventClick = new Object();
public event EventHandler Click
{
add
{
Events.AddHandler(EventClick, value);
}
remove
{
Events.RemoveHandler(EventClick, value);
}
}

#endregion
}
}






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


Jordan S. said:
I'm just wondering if this would work. Please note that I'm not asking
*how* to raise events. I'm clear on that. What I'm not clear on is the
sequence in which events are raised by custom controls relative to the
hosting Page, and therefore if the following specific arrangement would
even work.

What I'm looking to do is dynamically insert multiple custom composite Web
server controls onto a blank Page. This is no problem, I know how to do
this part.

What I need is for one of these controls to "broadcast" events of interest
to any other controls on the hosting Page that may be interested. But I do
not want for any of the controls on the page to directly know anything
about each other (hold references to each other).

So, to make this happen I am thinking that this would work:
A control gets notified - via the hosting Page - of the event originating
in another control.

Specifically:

1. During PostBack, control #1 raises an event (that is of interest to
Control #2).

2. The hosting Page is subscribed to the event in Control #1

3. The hosting page then raises an event of its own, passing along the
EventArgs received from Control #1.

4. Control #2 is subscribed to the Page's event [that is raised in step 3
above], and consequently receives notification (from the Page) that
includes a copy of the EventArgs-derived class sent from Control #1.

Will this work? Will ASP.NET, during PostBack, raise the events in the
correct sequence? (Control riases event ----- page raises another
ent ----- Control handles event raised by Page)

Thanks!
 
Back
Top