One of the biggest features of Silverlight since Version 3 is out-of-browser (OOB). This feature allows us to create an application in Silverlight that will be installed on the user's local machine. Once installed on the user's local machine, our application can interact with the desktop capabilities of the user's machine in various ways. Among the different integrations we get, we can read the machine's network state, show toast notifications, display web content, run applications on full screen, and much more. Silverlight 4 introduced a new powerful mode for OOB applications called elevated trust. Running our application in this mode, we can read local files and resources, show fewer confirmation prompts to the user, and use COM automation to communicate with other applications (such as Microsoft Office) or software APIs such as the speech API of the OS or drivers, which allows COM communication. An OOB application looks, and behaves, like any other regular software you know. The following screenshot, which is taken from http://www.seesmic.com shows an OOB Silverlight 4 application called Seesmic Desktop 2:
To get started with OOB applications, let's build our first OOB application. We will start with understanding how to install and uninstall applications and extend the application as we progress through the chapter.
The major difference between an out-of-browser application and a regular Silverlight application is, well, that it runs out-of-browser. To get a better understanding on how this mechanism works, we will build a super simple Silverlight application that allows you to install it on the desktop and shows you its current status (installed or not installed).
Create a new Silverlight 4 application in Visual Studio and name it Chapter6-SimpleOOB. Open the MainPage.xaml
file and add the following XAML code:
<Button x:Name="instBtn" Content="I'm in browser. click me!" Click="instBtn_Click"/>
There is nothing special here, just a button with an event handler for the Click
event, which we will handle soon. In order to make an application installable, we need to set it in its properties. Right-click on the project name in the solution explorer and click on Properties. One of the properties we can set is the Enable running application out of the browser option, as shown in the following screenshot:
Select the Enable running application out of the browser checkbox and click on the Out-of-Browser Settings button. The following screen will appear:
All of the OOB application settings can be set in this dialog box. Most of the settings, such as Window Title, or Width and Height, are self-explanatory. If you select the Set window location manually checkbox, you can specify how far from the top and left-hand sides of the user's monitor you wish to initially show the application. Another set of settings you should set are the different icon sizes. Each application has a different size of icons for different purposes in that application. The last three checkboxes are what we should focus on. They are as follows:
If we check the elevated trust checkbox, we get to set a new property—Window Style. This property sets how the window hosting the application will look. The different options you have for this property are Default, No Border, Single Border, and the most exciting option of them all—Borderless Round Corners. These modes (and the No Border mode) are also referred to as chromeless, as they remove any chrome from the application window. A chromeless application window offers designers much better control over how it will look, and it's one of the more popular choices when creating an OOB application.
Leave all of the default options intact, but check the elevated trust checkbox and click on OK. Save your project and switch over to the MainPage.xaml.cs
file.
Our main point of interest when it comes to dealing with OOB is the Application
object. In conjunction with the Current
object, we can get a reference to the current active application and check different properties of the application state. For example, we can check whether or not the application is installed on the user's computer. Other properties we can check include the installation state of the application, available updates, and so on. In addition, the object exposes different events we can register to, such as InstallStateChanged
, which handles changes in the installation states (installation, uninstallation, and so on) or NetworkAddressChanged
, which reports on the user's network state.
The first task of our application is to check whether or not the application is currently installed on the user's computer; and if it does, change the content of the button. First, register to the Loaded
event by adding the following line of code to the MainPage.xaml.cs
file's MainPage
constructor:
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
Next, add the MainPage_Loaded
method as follows:
void MainPage_Loaded(object sender, RoutedEventArgs e) { if (Application.Current.InstallState == InstallState.Installed) { ChangeUI(); } }
The code first checks the current installation state of the application. If it's already installed on the user's computer, the method will call another method—ChangeUI
, which changes the button content and disables it. The content of ChangeUI
is as follows:
private void ChangeUI() { instBtn.Content = "Application is out of browser!"; instBtn.IsEnabled = false; }
If we leave the code as it is, the change to the UI will occur only after the next time the users try to access our application. This is not good practice, as we wish the button's content and state to change as soon as we install the application. For that we can register to the InstallStateChanged
event of the Application.Current
object. This event fires every time the installation state changes and, thus, it is perfect for our current needs. Add the call to event handler in your constructor method, just below the call to the Loaded
event, as follows:
Application.Current.InstallStateChanged += new EventHandler (Current_InstallStateChanged);
Also, add the event handler as follows:
void Current_InstallStateChanged(object sender, EventArgs e) { ChangeUI(); }
The last remaining task is to actually call the Install
method and install the application.
Add the instBtn_Click
method as follows:
private void instBtn_Click(object sender, RoutedEventArgs e) { Application.Current.Install(); }
All it takes to install the application is to call the Install
method of the Application.Current
object.
Build your application but instead of running it the usual way, right-click on the Chapter6-SimpleOOBTestPage.aspx file in the web project, and click on View in browser.
You'll be greeted with the following screen:
Click on the button. The default installation screen of Silverlight pops up allowing you to select which shortcuts you wish to create and whether you want to allow the installation of the application. If you have uploaded icons in the OOB settings window beforehand, it will be shown in this installation menu as well. Click on Install. Immediately the button's content will change as follows:
On your desktop (if you selected to have a shortcut there), you shall now see a shortcut to the application as well!
Click on the shortcut, and the application will run outside the browser:
Uninstalling the application is a simple matter. Just run the application from the shortcut, right-click on it, and choose Remove this application.
We now have a basic OOB application up and running.
In many scenarios of using OOB applications, your application will need to know whether or not it is connected to a network or needs to detect network changes. Silverlight allows us to check for both of those conditions using the System.Net.NetworkInformation
namespace.
By using the GetIsNetworkAvaliable
method of the System.Net.NetworkInformation
namespace, we can tell if there is any sort of a network connection on the user's computer. It is important to note that having a network connection doesn't guarantee that the computer is connected to the Internet or can access the resources you are asking for. A good practice to fully detect connection to your resource is first check whether a network connection is available, and if so, call a service on the server you're trying to reach. If the call succeeds, you will be connected.
To detect network changes, the NetworkInformation
namespace exposes the NetworkAddressChanged
event. This event fires every time the network state of the user's computer changes. Let's see both of these concepts in action. Open the application that we have previously created in Visual Studio 2010, and then open the MainPage.xaml
file.
We will now add a simple UI element to tell us whether we have a network connection or not. Add the following code snippet just below the Button
element in LayoutRoot:
<StackPanel Height="30" Orientation="Horizontal" VerticalAlignment="Bottom"> <Ellipse Width="20" Height="20" Margin="20,0,0,0" x:Name="elNetwork"/> <TextBlock TextWrapping="Wrap" x:Name="tbNetwork" VerticalAlignment="Center" Margin="10,0,0,0"/> </StackPanel>
Now that we have the UI, let's add the login information. Open the MainPage.xaml.cs
file, and add the following code snippet inside the constructor method:
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged += new System.Net.NetworkInformation.NetworkAddressChangedEventHandler (NetworkChange_NetworkAddressChanged);
By using the preceding code snippet, we are registering to the NetworkAddressChanged
event and, thus, can change the UI based on the network change.
Next, add the ChangeNetworkUI
method, and call it from the NetworkChange_NetworkAddressChanged
handler:
private void ChangeNetworkUI() { if (System.Net.NetworkInformation.NetworkInterface. GetIsNetworkAvailable()) { elNetwork.Fill = new SolidColorBrush(Colors.Green); tbNetwork.Text = "Network is available!"; } else { elNetwork.Fill = new SolidColorBrush(Colors.Red); tbNetwork.Text = "No network detected..."; } }
Lastly, we need to call the ChangeNetworkUI
method from the Loaded
event so that it will show the initial state of the user's network. Change the MainPage_Loaded
method as follows:
if (Application.Current.InstallState == InstallState.Installed) { ChangeUI(); ChangeNetworkUI(); }
Build and run the application. If your computer isn't connected to any kind of network, you will get the result, as shown in the following screenshot:
As soon as I connect my computer to a network, the UI will change as follows:
A cool feature that got added to Silverlight 4 OOB applications is toast notifications. Even if you are unfamiliar with the term "toast notification", I'm pretty sure you've seen your share of it. Do you know how Outlook pops out a little window on the bottom-right corner of your monitor when a new e-mail arrives? That's toast notification. These notifications can be used for anything—from alerting the user that a new update has been applied to your application (which we will do in the next topic) to showing a preview of an e-mail or a new tweet that someone tweeted on Twitter. In Silverlight, handling notifications is done using the NotificationWindow
class. This class exposes different properties, such as Height, Width
, and Content
, for specifying the look of the window. Content
defines the content of the window and can contain any kind of framework element or even a user control. To actually show the notification window, we will call the Show
method while providing it with the number of milliseconds, we wish to show the window for.
Let's add a simple notification window to our application that will notify the user about changes in his/her network state.
Add the following method to your MainPage.xaml.cs
file:
private void ShowNotification() { NotificationWindow nw = new NotificationWindow(); nw.Height = 80; nw.Width = 200; TextBlock tb = new TextBlock() { Text = "Your network state has changed!" }; nw.Content = tb; nw.Show(5000); }
Find the ChangeNetworkUI
method and add a call to the ShowNotification
method at the bottom of it. Build and run the application, and you'll notice that every time the network state changes, a little notification pops up at the bottom-right corner of your screen, as shown in the following screenshot:
To show a nicer looking notification window, add a new user control to the project and name it ToastWin
. Change its XAML code as follows:
<Grid x:Name="LayoutRoot" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="15"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Border Background="Blue"/> <StackPanel Grid.Row="1"> <TextBlock Text="Network status" HorizontalAlignment="Center" FontWeight="Bold"/> <TextBlock Text="The network status has changed. please check your computer settings for more information." TextWrapping="Wrap"/> </StackPanel> </Grid>
Now change the value of the notification window's Content
property as follows:
nw.Content = new ToastWin();
Build and run the application, and once your network state changes, the new notification window pops up, as shown in the following screenshot:
When working with notification windows, keep in mind the following limitations:
When developing a regular Silverlight application, you have the benefit of being able to update your application from one central place and have all the users use the latest version of it. While OOB applications also support updates, their mechanism is a bit different. The Application
object, which we mentioned earlier, exposes a method called CheckAndDownloadUpdateAsync
. This method checks whether or not the XAP file on the server is newer than the XAP file of the user, and if so, downloads and updates the application. Once the download is completed, the CheckAndDownloadUpdateCompleted
event fires. This event's argument object (e) contains a Boolean property called UpdateAvaliable
, whose value will be true
if an update is found and downloaded. This is how we can notify the user that his application has just been updated. The code for this process is quite straightforward. Let's add the ability to check and update the application version of our sample application. Perform the following steps:
CheckAndDownloadUpdateCompleted
inside the constructor method of MainPage.xaml.cs:
Application.Current.CheckAndDownloadUpdateCompleted += new CheckAndDownloadUpdateCompletedEventHandler(Current_CheckAndDownloadUpdateCompleted);
Current_CheckAndDownloadUpdatecompleted
method:void Current_CheckAndDownloadUpdateCompleted(object sender, CheckAndDownloadUpdateCompletedEventArgs e) { if (e.UpdateAvailable) { MessageBox.Show("The application was updated!"); } }
If an update is available, a message box will pop up, informing the user about the update.
MainPage_Loaded
handler as follows:void MainPage_Loaded(object sender, RoutedEventArgs e) { if (Application.Current.InstallState == InstallState.Installed) { ChangeUI(); ChangeNetworkUI(); Application.Current.CheckAndDownloadUpdateAsync(); } }
That's it. If an update is available to the application, it will be downloaded in the background. Once it finishes, the message box will pop up informing the user of the recent change.
Silverlight 4 introduced the ability to display HTML content in OOB applications. Using the WebBrowser
control, it is now possible to render HTML pages and JavaScript in any OOB application. It's important to note here that only OOB applications support the WebBrowser
control, and if you try to use it in an in-browser application, it will not display anything.
To demonstrate the use of the WebBrowser
control, we will create a browser-like OOB application. Open the Chapter6-OOBHtml project in Visual Studio 2010. The UI here is pretty simple—a TextBox
control for entering an address for a website and a Button
control.
There are three ways to load content into a WebBrowser
control:
Setting the Source
property is an XAML-friendly option to use the WebBrowser
control. Add the following code snippet to the project's MainPage.xaml
file just below the closing element of StackPanel:
<WebBrowser x:Name="wbControl" Source="http://www.packtpub.com" Grid.Row="1"/>
If you run the application now, you should get the result, as shown in the following screenshot:
The live Packt website can now be seen inside your OOB application. As cool as that might be, our application currently offers no interactivity, as the user cannot change the displayed website. Let's change this now. Switch over to the MainPage.xaml.cs
file, and add the following code snippet inside the btnGo_Click
method:
if (tbAddress.Text != "") wbControl.Navigate(new Uri(tbAddress.Text, UriKind.Absolute)); else MessageBox.Show("Please enter a valid url");
The preceding code snippet uses the Navigate
method of the WebBrowser
control to change its source. The Navigate
method requires a single argument of the Uri
type. Build and run your application, and change the address in the TextBox
control at the top. Enter any address you wish into the textbox (in my example, I used http://www.yahoo.com), and click on the Go button. Your desired website will now be shown in your application.
The last method of loading content to the WebBrowser
control is the NavigateToString
method. Using this method, you can 'feed' the WebBrowser
control your own HTML code.
Let's change the logic of the button's Click
event to check if we have entered a URL address (starting with http)
or direct HTML code (starting with<html>)
. If we have typed an address, then we should continue using the Navigate
method; if not, we will use the NavigateToString
method. Change your btnGo_Click
method as follows:
private void btnGo_Click(object sender, RoutedEventArgs e) { if (tbAddress.Text != "") { if(tbAddress.Text.IndexOf("http")==0) wbControl.Navigate(new Uri(tbAddress.Text, UriKind.Absolute)); else if (tbAddress.Text.IndexOf("<html>") == 0) { wbControl.NavigateToString(tbAddress.Text); } else MessageBox.Show("Please enter a valid url or HTML code."); } else MessageBox.Show("Please enter a url or HTML code."); }
The code looks quite similar to the previous code snippet we wrote. The only difference here is that we check whether or not we have entered a URL of a website. If not, we will use the NavigateToString
method and pass it the HTML code we wrote in the textbox. The result of typing<html><body><div style='background-color:blue;color:white'>I'm a div</div></body></html>
will be as follows:
This chapter should get you started working with out-of-browser applications. OOB applications offer a lot of freedom while creating your applications. A feature we haven't covered in this chapter is working with COM Interop. While this feature is out of the scope of this book, I strongly recommend reading Justin Angel's post on COM located at http://justinangel.net/CuttingEdgeSilverlight4ComFeatures.
13.59.197.213