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 to Event.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.

Tags: ASP.NETSublayout
comments powered by Disqus