How to make your Sublayouts talk to each other
This article describes how to pass data between Sublayouts using the Sitecore event pool. This is a great way to help build a flexible solution from loosely coupled, re-usable components.
07 May 2014
To raise and subscribe to events in Sitecore the Sitecore.Events.Event
class is used. The key methods used are
//to raise an event:
public EventResult RaiseEvent(string eventName, params object[] parameters))
//to subscribe/unsubscribe to/from an event
public static void Subscribe(string eventName, EventHandler handler)
public static void Unsubscribe(string eventName, EventHandler handler)
//extract the event arguments
public static object ExtractParameter(EventArgs args, int index)
public static T ExtractParameter(EventArgs args, int index)
public static object[] ExtractParameters(EventArgs args)
Sublayout code to raise a Sitecore event
An example Sublayout is shown below. The ascx markup contains a button called 'Button1' and a text box called 'TextBox1'. When the button is clicked an event is raised passing the value entered in the textbox.
public partial class EventRaiserSublayout : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
var message = TextBox1.Text;
Sitecore.Events.Event.RaiseEvent("SomeEventName", message);
}
}
Sublayout code to subscribe/unsubscribe to a Sitecore event
The second sublayout subscribes to the event raised by the first and updates a label component 'Label1' with the value passed in the event parameter.
public partial class EventHandlerSublayout : System.Web.UI.UserControl
{
private System.EventHandler eventHandlerRef;
protected void Page_Load(object sender, EventArgs e)
{
eventHandlerRef = EventHandlerMethod;
Sitecore.Events.Event.Subscribe("SomeEventName", eventHandlerRef);
}
private void EventHandlerMethod(object sender, EventArgs e)
{
if (e != null)
{
Label1.Text = Sitecore.Events.Event.ExtractParameter(e, 0) as string;
}
}
protected void Page_Unload(object sender, EventArgs e)
{
if (eventHandlerRef != null)
{
Sitecore.Events.Event.Unsubscribe("SomeEventName", eventHandlerRef);
}
}
}
There are a few important points to note in the code above
- There's no
if(!Page.IsPostback)
in Page_Load. This is because the event has to be re-wired on each page load. - You need to unsubscribe from the event by calling
Event.Unsubscribe
. If this is omitted, you will see that your event handler gets called multiple times for each event. - You need to have a class-scope variable to hold a reference to the event handler - this allows
Event.Unsubscribe
to work as it needs the same object reference that was passed to Event.Subscribe.
Tips for working with Sitecore events
- Define event names as static or readonly properties in a separate class to avoid 'magic strings'
- Use a 'namespace' for your events to minimise the possibility of name collisions. e.g.
"MyProject:MyEvent"
- Don't pass a long list of parameters to
Event.RaiseEvent
, instead create your own EventArg classes defining the data passed with your events, this way if you add an event parameter to your class, you won't need to create more calls toEvent.ExtractParameter
- Note: your EventArg classes don't have to inherit from System.EventArgs
- Events can work via AJAX if your sublayouts use an
<asp:UpdatePanel>
Gotchas
For this to work, caching must be turned off. This applies to any Sublayout which handles post-backs. Note that you can leave caching turned on for the other Sublayouts on your page.