Phil Trelford's Array
POKE 36879, 255

Silverlight 5: Multiple Windows

February 3, 2012 17:56 by phil

Silverlight has become increasingly popular for applications that run both in-browser and on the desktop like Sky’s Go and Netflix. One of the key new features in Silverlight 5 is multiple window support for desktop applications (also known as Out-of-Browser (OOB) applications).

Why Multiple Windows?

Multiple windows are common in quite a few applications:

  • graphics packages like GIMP
  • video production software like Adobe Premiere
  • music editing software like CakeWalk
  • IDEs like Visual Studio
  • the long tail of Line-of-Business (LOB)/Enterprise/Scientific applications

Multi-window apps let users optimize usage of screen real estate across multiple displays.

    Why Silverlight?

There are a number of scenarios where you might choose Silverlight over say WPF:

  • you have an existing application written in Silverlight
  • your application needs to run both in-browser and on the desktop
  • installing the full .Net framework in your target environment is problematic

On the flip side, if you're developing a new application that must support multiple windows and that doesn’t need to run in the browser and you have full control over the target environment, then WPF is probably a good choice. WPF also provides better support for dragging and dropping between windows. Yet another choice might be to build your application to target both WPF and Silverlight.

WinRT

Then to add some more factors to the equation, there’s the new Windows Runtime – WinRT:

winrt

From the diagram above you can see that WinRT will only run on Windows 8 which isn’t even released yet, and WinRT is not intended for desktop applications. It is also possible to create desktop applications for Windows using HTML and JavaScript, check out Cut the Rope. Practically though if you’re building an application that can run on the desktop using managed code the choice is still between WPF and Silverlight.

Getting Started

There are a good number of articles already written on getting started with multiple windows in Silverlight. Simply pick your favourite evangelist:

Cutting to the chase:

new Window().Show();

RootVisual

Nearly a year ago Mike Taulty wrote:

As an aside, I’ve seen a number of scenarios in Silverlight where developers use Application.Current.RootVisual as a way of finding the root of the visual tree – this kind of code might need revisiting in a Silverlight application that has content in multiple windows because the RootVisual does not necessarily provide a “root” for content living in a separate window.

Q: So how do you find the RootVisual in a multi-window environment?

A: Call Window.GetWindow and then look at the Window.Content.

Focus

Q: How do you find the focused element in a multi-window environment?

A: Call FocusManager.GetFocusedElement with the answer from Window.GetWindow.

Popups

Q: How do I get Popups to appear in a secondary window?

A: Call Popup.SetWindow with the answer from Window.GetWindow.

Issues

Q: So far calling Window.GetWindow solves all, where are those inevitable niggling issues?

A: All over the shop:

  • A lot of third party software (including Microsoft’s) is going to still assume there can be only one window via Application.Current.RootVisual.
  • If your doing custom chrome (no borders) then maximize on secondary displays is broken.
  • Don’t even think about trying to set the WindowStyle to BorderlessRoundCornersWindow if it isn’t the main window.
  • Move controls between windows at your own risk. Certain controls like Tooltips currently cache the window they first appeared in. Moving controls that use tooltips to another window may prove fatal.

Silverlight Toolkit

Both the ChildWindow and ContextMenu controls fail in a multi-window environment

I’ve created an open source project on CodePlex where they can succeed:

Telerik

At time of writing Telerik’s RadContextMenu, RadWindow & RadComboBox do not work in a multi-window environment.

Some of the issues are expected to be fixed in a mid-February release.

Summary

It’s clearly early days for Silverlight 5 multi-window support and it looks like third party vendors are still playing catch-up. That said, with the advent of SiIlverlight 5, and it’s support for multiple windows, the lines between desktop and browser application are blurred a little bit more.


Tags:
Categories: Silverlight | .Net | C#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Silverlight 5’s ChildWindow in Multiple Windows

January 29, 2012 14:34 by phil

A ChildWindow in Silverlight is a control that can be displayed over a parent window blocking its interaction. Silverlight 5 introduces multiple window support for Out-of-Browser (OOB) applications with elevated trust. Unfortunately the ChildWindow control is not currently multi-window aware which means, as is, a child window may only appear in the main window.

Finding the code

With the release of Silverlight 5 the ChildWindow control is part of the main distribution, where previously in Silverlight 4 it was bundled with the Silverlight Toolkit. Therefore to change the code to make the control multi-window aware we’ll have to resort to the Silverlight 4 Toolkit source, conveniently available on CodePlex.

Examining the code

The ChildWindow class makes 2 assumptions that prove false for multi-window apps:

a) the parent control will always be the current application’s RootVisual, e.g.

private static Control RootVisual
{
    get { return Application.Current.RootVisual as Control; }
}

b) the size of the parent window is based on the application’s host window Content, e.g.

Application.Current.Host.Content.Resized += new EventHandler(Page_Resized);

Fixing the code

In terms of code changes, the main one is to allow the parent window of the ChildWindow to be specified using a SetWindow method (as implemented by the Silverlight 5 Popup control). Then to simply replace all references to content made via static properties of the Application class with references to content via the specified window.

To use the updated control we will also need to create a new Silverlight 5 project to host it in and copy the related files over from the Controls project of the Silverlight.Controls.Sdk solution, including the ChildControl’s style from the project’s generic.xaml.

Get it now

The source is available on CodePlex: Silverlight Multi-Window Controls


Tags:
Categories: Silverlight | C# | .Net
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Silverlight 5 Toolkit’s ContextMenu in Multiple Windows

January 29, 2012 01:25 by phil

Silverlight 5 provides multi-window support for Out-of-Browser (OOB) applications with elevated trust. Unfortunately the ContextMenu provided in the December 2011 release of the Silverlight Toolkit is not multi-window aware which means that context menu’s opened from secondary windows only appear in the main window.

I’ve added a work item on the Toolkit’s issue tracker, but if in the meantime like me you can’t wait for it to be fixed, you can follow the steps below.

Note: this is also an issue in the current release of Telerik’s Silverlight RadControls.

Finding the code

First off you’ll need to get the source code for the Silverlight 5 Toolkit which somewhat surprisingly is not available through the Source tab on the CodePlex site. Instead you can download and install the Silverlight 5 Toolkit - December 2011 release MSI. Then locate the source code distributed in a zip file:

 %Program Files%\Microsoft SDKs\Silverlight\v5.0\Toolkit\dec11\Source\Source code.zip

The context menu code is part of the Controls.Input.Toolkit project of the Controls.Toolkit solution.

Underlying issue

Underneath the Silverlight 5 Toolkit’s ContextMenu class uses the Silverlight Popup class to display content on top of existing Silverlight content. In Silverlight 5 the Popup class has a new method SetWindow to set the window it pops up in, however it is not being called.

Fixing the code

To fix the code we’ll also need to discover the window that the user has clicked in using the Window.GetWindow static method.

1) Add a _currentWindow field to the ContextMenu class:

/// <summary>
/// Stores a reference to the current window.
/// </summary>
private Window _currentWindow;

2) Set the _currentWindow value in the HandleOwnerMouseRightButtonDown method:

void HandleOwnerMouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
  if (e.OriginalSource is DependencyObject)
  {
    _currentWindow = Window.GetWindow(e.OriginalSource as DependencyObject);
    _rootVisual = _currentWindow.Content;
  }
  OpenPopup(e.GetPosition(null));
  e.Handled = true;
}

2) Call the Popup’s SetWindow method in the OpenPopup method:

  _popup = new Popup { Child = _overlay };
  _popup.SetWindow(_currentWindow);

Get it now

The source is available on CodePlex: Silverlight Multi-Window Controls


Tags:
Categories: Silverlight | C# | .Net
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed