FloatingWindow — multi-windows interface for Silverlight and WPF

The only thing that limits the power of the Silverlight is lacking of multi-windows interface. The FloatingWindow library contains a few controls that can help you to create such UI. But before you start your reading - click on the FloatingWindow demo link to see whether it can be interesting for you. If yes - take the latest version (currently v2.0.2) of the library here:

Download
FloatingWindowControl project - 169KB (Version 2.02 for Silverlight 4)
FloatingWindowWPF project - 120KB (Version 1.0 for WPF)
License: The Code Project Open License (CPOL)

If your browser has installed Silverlight plug-in, you will see a demo application like that:

FloatingWindow demo

What's new in the version 2.0

Here is a short list of what was added or changed in the version 2.0:

  • Completely changed the IconBar and the BootstrapButton controls.
  • Added a BottomBar control containing the bootstrap button.
  • Added new styles to make the windows more "skinnable".

Introduction

Though floating windows are common in graphics applications, there are not too many such controls in the Silverlight. One of the best is Tim Heuer's FloatableWindow control.

Starting this project, I just wanted to add a few functions to the existing control. But it turned out it was easier to rewrite it completely. Finally, only a few original lines of code had left after my rework. I added the following functionality:

  • Window can be resized by dragging any edge or a corner
  • Added possibility to snap in moving or resizing window to the nearest window's boundary
  • Window can be minimized, maximized and restore its position and size
  • Window can be opened in modal mode
  • Window can save and restore its size and position
  • Added an icon bar, displaying minimized or all windows
  • The icon bar can display a snapshot of a minimized window or a bitmap icon
  • Window can move under its own inertia.

Exploring FloatingWindow

The library contains a few clases. Some of them are controls you could use directly. Other classes are just internal helpers. Most valuable classes and their relations can be illustrated by the following sketch:

Most useful classes

Where the most important elements are:

ElementsDescription
FloatingWindowA base class of the resizable windows
FloatingWindowHostA Canvas element containing floating windows
IconbarA panel containing window icons
Bootstrap ButtonA button opening/closing the Iconbar
Bottom BarA container control that can host any other controls

Detailed list of class members and their properties you can find in the FloatingWindow Documentation section.

Getting Started

Creating Windows

The windows are "floating" in the FloatingWindowHost - a Canvas control, which shall be created first, for example, in the markup:

The next step - we shall create and add our windows to the host:

Created window is hidden. The FloatingWindow class has four overloaded methods Show(). The first overload takes no parameters and displays the window in the center of the hosting container. The second and third overloads show the window in the specified coordinates.

There is another option: to restore window size and position saved when the window was closed. Don't worry about saving these parameters. They will be automatically stored in the IsolatedStorage at the close of the window if you specify a unique window's Tag. You can set it during runtime or in the XAML:

Now you can call the RestoreSizeAndPosition() method to show the window in the previously saved coordinates:

In the version 1.2 new ShowModal() method was added to display a floating window in modal mode. It blocks access to underlying windows displaying an overlay above them. The color of the overlay is defined by the OverlayBrush property.

Modal Window

Like the ChildWindow it has a DialogResult property, which can be retrieved on windows closing:

The major distinction between the modal window and the ChildWindow is that the last one blocks access to the whole area occupied by the Silverlight application, while the floating window in modal mode - only parent FloatingWindowHost.

If you need to know which window becomes active (gets focus), you can subscribe to the Activated or Deactivated events added in the version 1.2.1 (see the MainPage.xaml.cs):

Now windows are displayed and we can switch between them, move and resize. Selected window becomes topmost and gets focus. If we want a window to be displayed always above others, we can set its TopMost property to true.

Appearance of the window is defined in the generic.xaml file.

Honey, I Shrunk the Windows

When we move or resize a window it sticks to the nearest boundaries. Maximal distance at which the window attracts to other windows is 5 pixels and is defined in the SnapinDistance property. If you don't like the windows sticking close to each other, you can specify non-zero SnapinMargin - a gap between adjacent windows. "Mind The Gap" as they say in London.

We can enable or disable resizing setting ResizeEnabled property. Besides, it is possible to disable resizing by one of the coordinates. For example, if we set window's MinWidth equals to its MaxWidth the window can't be resized by the X coordinate.

Writing code for resizing I created two interesting (at least for me) by-products: ResizeController and SnapinController. They are more or less independent from another parts of the code and I am going to use them in my other controls.

Dude, where is my Window?

If we provide a possibility to minimize windows, we shall give quick access to them. And not only to minimized ones because some windows can be moved out of the visible area of the windows container. That's why I recommend to set ShowMinimizedOnlyInIconbar property to false.

The icon bar emerges each time when we press the bootstrap button at the bottom of the windows container and hides when the mouse cursor leaves the bar. It contains windows' thumbnails ordered by the IconText. If you don't want to display a window's icon on the icon bar, set its property ShowInIconbar to false.

Window's thumbnail is displayed as a snapshot of the window if the Icon property is not set. Otherwise, the FrameworkElement set by the property will be displayed. For example, look at the markup of the WindowWithChart.xaml:

It defines the MyIcon UserControl as an icon of the window. Nice looking, isn't it? If you want to use an image as an icon, you shall specify its dimensions:

How to add it to your project

Here you have a short step-by-step instruction:

  1. Find the FloatingWindowTemplate.zip in the downloaded archive and copy the ZIP file to the ItemTemplates folder of your Visual Studio. On my machine it is the "C:\Users\Eugene\Documents\Visual Studio 2010\Templates\ItemTemplates\Visual C#" folder.
  2. Add the SilverFlow.Controls.dll as a reference to your Silverlight project.
  3. Copy the resource dictionary generic.xaml from the SilverFlow.Controls project to your Silverlight project and add it to your application resources.
  4. Right-click on your Silverlight project, select "Add > New Item...", and select the FloatingWindow Control item template.
  5. Build the project.
  6. Add the FloatingWindowHost control to your page, hosting the "floating" windows. See the MainPage.xaml how to do that.
  7. Add a code, creating and displaying the "floating" windows.

History

  • October 27, 2010. Fixed bug in ResizeController causing stack overflow. Thanks to Michael Washington.
  • February 12, 2011. Version 1.2. Fixed a few bugs. Reworked the Iconbar. Added modal mode.
  • May 12, 2011. Version 1.2.1. Fixed some bugs. Added Activated and Deactivated events. Added RestoreSizeAndPosition method.
  • June 5, 2011. Version 1.2.2. Added WindowButton class and changed style of the Minimize/Maximize/Close buttons.
  • August 10, 2011. Version 1.3. Added inertial motion of a window.
  • September 14, 2011. Version 1.3.1. Added styles for the window buttons.
  • October 3, 2011. Version 2.0. Changed IconBar and BootstrapButton controls. Added BottomBar. Added new styles.