Divelements
Because everything starts with the presentation layer
Learning
 Wednesday, December 12, 2007, 2:43 AM   Home Products How to Buy Store Support Corporate  
Dockable Windows

Not enough people know about dockable windows. Some people know what they are but not how to use them properly, some people don't realise how developing properly with them can help enforce good application design principles, and some people try to use them for entirely inappropriate things. Some people know all about them, and if you're one of those people you don't need to be reading this article.

The type of dockable window we will be discussing in this article are the type introduced in the last few versions of Microsoft Visual Studio, which makes very good use of them. There are competing products which also have dockable windows, but these mainly try to copy the Visual Studio behaviour so we will not discuss them.

This document is intended to be a "best practice" guide which can help you decide whether you need dockable windows, and if you do, how best to implement them. Of course, we also tell you how our own product can help you.

The Problem

The problem, like so many user interface problems, is one of clutter. You need many different types of input/output/navigation tools available - for the rest of this article we will refer to these tools as "windows" for want of a better description. A "window" will be one logical tool, which may of course consist of multiple controls that work together in order to collect, display or control data in as meaningful a manner as possible.

You could put every type of window in to a separate form in your application, and show these forms (owned by your main application form) when the user wants to use the tools. This is a pretty good idea, and allows you to easily keep the functionality of these windows within their own classes, assuming you're using a development environment where a form is its own class. Thus your encapsulation is doing great and you're feeling pretty pleased with yourself, until you realise your users will expect these forms to always be in the same place from one run of your application to the next. This is of course entirely possible, with some work. However, your user may find themselves irritated by the amount of forms they need constantly open (they will always have a favourite few) and wish they were incorporated in to your main application UI.

You could incorporate all your windows in to your main application UI. Divide your main working area so that part of it is devoted to showing the tools the user might need while using the "main" portion. The user will feel more attached to the windows because they're not having to switch to other forms all the time, and accessibility using the keyboard is made slightly more intuitive too. The problem with this solution is that it does not scale - what happens when your application has 20 different windows that can be shown? You need to have separators between them, which will result in tiny windows, or "tabs" to switch between them, in which case you can only view one at once. This situation is not quite as bad as it sounds, because you have four sides of your main UI on which you could place these systems, but it still does not scale.

So let us review the main points that need to be addressed should you be thinking about building an application with a moderate degree of complexity. You need to be able to display an arbitrary number of tool windows to your user, but:

  • They must be in a position as close to your working area as possible so as not to take the user's attention away
  • In order to maximize working area, the user must be able to configure where they appear (in an intuitive way)
  • Keyboard navigation is an absolute must, so this needs to be factored in
  • All windows need to maintain their exact positions and proportions from one run of your application to the next
  • From a developer tools standpoint, you do not wish your life to be made any harder by adoping this approach.

The Solution

The Visual Studio 2005 IDE

The Visual Studio 2005 IDE, making good use of pinned, unpinned and floating dockable windows. Click for a full size image.

Is, of course, dockable windows. Imagine a system where your window entities can exist anywhere in and around your application's main window. The user is able to choose where to put a window by visually dragging it there. Locations can include:

  • Floating on its own, in which case it can be moved on to another monitor and sized as large as the users wants
  • Attached to any side of your form, in any position with respect to other windows that may be attached there too
  • Attached in the same place as another window, in which case tabs can be used to flip between them
  • Attached but "unpinned", which refers to a state where they are collapsed to a thin bar at the edge of the form, ready to pop up and be used
  • Or even taking up the main space in working area of the form, if the window will ever be the user's primary point of focus.

This is a system proposed to solve all the problems discussed above. If you have a simple application, dockable windows are not the right solution, and one of the other proposed systems such as dedicating part of your form to displaying tools at all times, would be more appropriate. Consider Microsoft Office - they do not have dockable windows in the sense or scope discussed here, but they do have dockable toolbars and task panes. These are limited (purposefully) so they cannot be grouped together in the same place or unpinned.

From a development standpoint, we will assume that you are using a reasonably high level OOP language, and that you would like to write the code for your windows in their own classes which are independent from any other window functionality. Also, one of the most important things about successfully implementing dockable windows is the concept of delay loading. Your window objects should not be instantiated until they are actually needed by the user, thereby optimising load time of your main user interface.

Docking Hints and User Docking

Everett Hints

The rubber band hint shown when docking a window by the side of an existing window in Visual Studio 2003.

"Docking hints" is the name for the visual cues that appear while the user is in the process of visually moving a window from one location to another. Being intuitive should be the utmost priority here, as this is something they will want to do often and not have to think about it. The user should be able to initiate a docking operation by dragging a window's tab, or window's titlebar (in which case the operation could apply to many windows in that space). What happens next depends upon the docking hints.

Visual Studio 2003 ("Everett")

In this version of Visual Studio, a rubber band is drawn to roughly indicate the position the window would assume if you dropped it at any given location. To dock it to the side of the form, you move the mouse near the edge of the form. To dock it to the side of any window that is already docked, you move the mouse near the edge of the docked window. To dock it in the same place as a window (thus adding to that collection of "tabbed" windows) you move the mouse over the titlebar of the window.


Whidbey Hints

The directional indicator hint shown when docking a window by the side of an existing window in Visual Studio 2005.

Visual Studio 2005 ("Whidbey")

Although this version did not add any new windowing capabilities to its dockable window system, the docking hints completely changed in an attempt to be more intuitive. A lot of people simply failed to understand what they could do with windows with the previous incarnation.

When dragging a window or set of windows, a translucent coloured rectangle is drawn to show the eventual position of the window. This is more visually pleasing than the dated rubber band effect. At all times when the mouse pointer is within the bounds of your form, four small arrows are drawn to represent the outside edges of the form. Moving the mouse over these arrows results in your window being docked there. While the mouse pointer is within the middle of your form (i.e. within any windows already docked to the sides) a directional indicator is shown so the user can choose to dock on any of the inner edges of the form. When moving the mouse pointer over a window that is already docked, the same floating directional indicator is shown to allow docking on any side of that window or "joining" it to form a tab.

The Dos and Don'ts of Dockable Windows

With a great tool like dockable windows, it is easy to over-use its functionality and end up creating user interfaces that are more confusing or nonstandard than the original interface problem presented was. As a provider of a dockable windows tool, we have seen instances of this, so here are a few points that illustrate the best practices of implementing dockable windows.

  • Don't try to restrict where the user can put any window.

    The whole point of a dockable windows library is that the user can place any window wherever they like. If the user wants to put a window in what you consider a silly place, let them do it. If you want to restrict window placing or movement, chances are you should be using a simpler UI paradigm than dockable windows. Any tool window should be floatable, dockable to any position on the edge of your main form, and closable.

  • Do always persist window state from one application run to the next.

    There are few user interface experiences worse than configuring one just how you like it, and then having the application revert to its former state. Most dockable window toolkits provide easy functions for persisting and restoring layout information as an XML string or similar, so use them.

  • Don't attempt to reflect the state of all your windows anywhere else.

    Sometimes people add an icon to a toolbar for all potential windows in their application, and set it to a "checked" state while the window is open. The user does not need to be told when a window is open, they can see it for themselves. Your application should not care whether a window is open or closed - this choice should be left entirely to the user.

  • Do make all windows accessible via your View menu.

    Every window should have an entry in your View menu (or a submenu). This serves two purposes - firstly, all your windows are closable (they are closable, right?) so the user needs an intuitive way of bringing them back when they realise they have lost them. The View menu is the first place they'll look. Secondly, this solves the keyboard accessibility dilemma. By assigning a memorable keyboard shortcut to each window, the user will quickly remember the shortcuts for their favourite windows and stop having to reach for the mouse.

    Remember that even though you are creating menu items for your windows, you do not need to reflect the current state of the windows in the items. Some people even go to the effort of disabling menu items when their windows are open. The View menu items should, whatever the state of your user interface at the time, bring the window up and set focus to it.

  • Don't have dockable windows in the middle of your form.

    Quite a few people want to do this, despite the fact there is no UI precedent for it. We are not talking about tabbed documents (they're fine) but actual dockable windows in the centre of the form, creating a form that is entirely comprised of dockable windows. The main problem with this is, what if the user closes or undocks the centre-docked window? You are left with a screaming void in the middle of your form, and it is not intuitive to dock a window back in the middle when you are used only to attaching them to the sides.

    When using a dockable windows library, the library goes to a great deal of effort to clear the middle, working area of your form for other controls.

  • Do have a great "default" window layout for your users.

    All this flexibility is great, but the default window layout should be well thought-out and intuitive. Sometimes applications need to change state, for example Visual Studio has many application states - the most common are edit and debug mode. You can use the layout persistance APIs offered by your framework to switch states, and provide a good default window layout for each.

  • Don't have too many child controls in any one window.

    That does not mean don't have complex windows, but 95% of the time a window should consist of a list (of items, or text) and a means of manipulating that list (a toolbar or means of selection). If you have something that requires multiple inputs from the user, it will become the main focus of the user and should be displayed as a form on its own.

  • Do make sure your windows are keyboard accessible.

    We touched on this already, in terms of the user getting focus to each window. But what if they want to get out of the window again? When if they want to close the window? What if they want to move the window to another location on their form, or to access a context menu that is relevant only to that window? What if multiple windows are docked at the same location, separated with tabs? Always ensure your dockable windows library fully supports standard keyboard methods of navigation.

How we can Help

Divelements SandDock

Our product, SandDock, addresses every concern touched on in this article. It can achieve every kind of window layout achievable with the Microsoft Visual Studio environment, and makes it very easy to do so from a development standpoint. Its default behaviour is to allow the user freedom to dock, float, move and hide any window however they choose, although this can be restricted if necessary. By default all your windows will be keyboard accessible.

All your windows can be designed in isolation, as separate classes, maintained by different developers if necessary. Using SandDock you get a visual designer for windows just like you do for normal forms, and when you are ready to use instances of them in your application you can dock them there easily using entries that are automatically added to your toolbox for each one.

Design and content Copyright © 2003 - 2007 Divelements Limited. Content may not be reproduced without permission.