Phillip Trelford's Array

POKE 36879,255

Silverlight 5 Toolkit’s ContextMenu in Multiple Windows

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.

There are bugs open on MS Connect and 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

Pingbacks and trackbacks (1)+

Comments are closed