Notification “Toast” For In-Browser LightSwitch Apps Using Growl For Windows

So what is “toast”, apart from a tasty component of sandwiches and breakfasts? It refers to those notification windows that pop up above the Windows system tray – a nice alternative to the bad old days when developers alerted users with an annoying stream of dialog boxes that demanded a click to proceed.

In Silverlight Out-of-Browser applications (and therefore LightSwitch OOB as well), we can use the NotificationWindow class.  With Silverlight 5, which is the default target for the client in the new beta of LightSwitch for Visual Studio 11, we can access in-browser some features previously reserved for out-of-browser, but this comes with certain limitations (Internet Explorer only) and extra setup (you must either use group policy settings or registry settings on each client machine to enable elevated trust apps in-browser).  So for in-browser use, most LightSwitch applications may not be able to take advantage of Silverlight’s NotificationWindow class.

There are other shortcomings of the NotificationWindow class as well.  One is that it can display only one notification window at a time.  Another is that it doesn’t implement a queue – you have to handle that yourself otherwise competing notifications may override one another.

As an alternative, providing more flexible “toast” that works in-browser in either Silverlight 4 or 5 and doesn’t require elevated permissions, you can take advantage of one of the third party notification window managers, such as Snarl or Growl For Windows.  These provide queueing of notifications, multiple notifications on window at once, forwarding notifications to a remote machine or iPhone, and can even be configured to tweet your notifications.  Connectors are available for .NET, Javascript, and more.

For this example, I’ll be using Growl For Windows, so you’ll need to install it first.  You’ll also need to configure it to “Allow notifications from websites”.

Create a new LightSwitch project.  Go to our application properties on the Application Type page and switch the Client to “Web”.

In the Solution Explorer, switch to “File View” for your LS project.

Download the Growl For Windows Javascript Connector and add the growl.js and GrowlFlashConnector.swf files to your project (copy from explorer, paste into the solution in the solution explorer… or drag and drop – the files should be at the top level… the same level as default.htm)

Edit the default.htm file in your project – you may need to click “Show All Files” in order to see the “default.htm” file listed..  Inside the <body> section at the top, add

<div id="growlconnectorcontainer"></div>

In the <head> section, add

    <script type="text/javascript" src="growl.js"></script>
    <script type="text/javascript">
        function register() {
            var application = new Growl.Application();
   = "LightSwitch Example App";
            application.icon = "";

            var notificationTypes = new Array();
            var nt1 = new Growl.NotificationType();
   = "NT1";
            nt1.displayName = "Notification Type 1";
            nt1.enabled = true;

            Growl.register(application, notificationTypes);

        function notify(notificationType, title, text, icon, priority) {
            var notification = new Growl.Notification();
   = notificationType;
            notification.title = title;
            notification.text = text;
            notification.icon = icon;
            notification.priority = priority;
            Growl.notify("LightSwitch Example App", notification);

        window.onload = function () {
            var config = {};

In a real world application, you’d want to include your javascript in an external .js file instead of embedding it in the default.htm, but let’s keep it simple for now.  Save changes and close the default.htm file.

Open “growl.js” and go to File…Advanced Save Options and make sure encoding is set to UTF-8 with Signature. If you fail to do this, it may work fine under Internet Explorer, but give you a “Failed to invoke: register” error when running under Firefox or Chrome.

Right-click on our project in the solution explorer and choose “Unload Project”.  Right click again and choose “Edit”.  Search for _BuildFile and add the following below the </_BuildFile> for default.htm:

<_BuildFile Include="growl.js">
<_BuildFile Include="GrowlFlashConnector.swf">

Save changes and close the file, then right-click on your project and choose “Reload Project”.

Add a new Editable Grid screen with nothing selected in the Screen Data dropdown. On the screen create a button “TestGrowlNotify” and edit the Execute code for the button, adding the following:

Dispatchers.Main.BeginInvoke(() =>
  HtmlPage.Window.Invoke("notify", "NT1", "Test Notification",
    "This is a test of the notification system",
    "", "Normal");

In this example, I’m using an external URL for the icon, but it can be a file path, a URL, or an array of bytes representing the raw binary data.

add the following in the usings section at the top:

using System.Windows.Browser;
using Microsoft.LightSwitch.Threading;

If you are using LightSwitch 2011 instead of the new LightSwitch for Visual Studio 11 Beta, then you may need to add a reference to System.Windows.Browser. To do this, switch to “File View” mode for your solution, right-click on the “References” folder in the client project, choose “Add Reference”, then select the System.Windows.Browser assembly.

Our approach is to use an HTML bridge to invoke methods in a Flash control, which in turn interfaces with Growl.   We first register our application with Growl and give it a list of notification types that we plan to use.  This allows users to

choose to ignore certain notification types, forward them to other machines or email accounts, etc.  Once registered, we just call notify and specify the type of notification, a title, some text, an icon, and a priority.

Run the project and click on your “Test Growl Notify” button and you should see a notification pop up!  This technique should work on both Windows and OS X.

It doesn’t handle OOB apps.  I’ll cover how to handle that issue in my next article.