Introduction

Recently, I started a project for porting a Windows Forms application to WPF. I was quite a novice in WPF, so at first I was considering using some type of Windows Forms interoperability. In particular, the WinForm application has cool docking functionalities that I wanted to port to a newer version. As I was going deeper into WPF technology, I discovered a new world that radically changed my initial ideas. In this article, I wish to share a library that implements the Windows docking feature in pure WPF without any Win32-interop.

Using the code

There are three fundamental classes: DockManager, DockableContent and DocumentContent. DockManager is a class responsible for managing the main window layout. Pane represents the window area that can be docked to a border. Each Pane contains one or more ManagedContent elements, which precisely refer to a window content element of the client code. Using this library is straightforward. DockManager is a user control that can be easily embedded into a window. For example, the following XAML code creates a DockManager in a DockPanel:

Ib order to be dockable, a window must derive from DockableContent. Deriving from DockableContent indicates that the window content can be hosted in DockablePane. Windows are initially docked either where you set the Show member call or, by default, to the left border. The last thing to see is how to add a document window. A document window is a particular window that can't be docked to the main window border. It lives only in DocumentsPane which, as DockablePane, is a particular kind of Pane. The following code adds a document window with a unique title to DockManager:

Points of interest

Exactly how is docking realized? I implement a simple algorithm here to manage relations between windows that are docked. DockingGrid contains code to organize Pane in a logical tree. DockManager calls DockingGrid.ArrangeLayout in order to organize the window layout. You also use DockingGrid.ChangeDock when you need to dock a Pane to a main window border. The following image shows a logical tree of panes. Don't get confused with the WPF logical tree.

Each node is a group of either two Panes or a Pane and a child. To arrange the layout, DockingGrid creates a WPF grid for each group with two columns or two rows, depending on split orientation. I hope the image is self-explanatory. Anyway, feel free to ask for more details if you are interested.

From version 0.1, the library supports floating windows, as you can see in VS. A floating window is an instance of the FloatingWindow class. It' s a very particular window because it needs to "float" between two windows. One is the parent window, MainWindow in this case, which is usually the main application window. The other is a transparent window owned by FloatingWindow itself, which is shown during dragging operations.

As you can see in the previous image, FloatingWindow supports useful switching options through a context menu on the title bar. In WinForms, controlling a non-client window area means overriding WndProc and managing relevant messages like WM_NCMOUSEMOVE.

In WPF, we have no access to messages posted to a window. This is because everything is controlled by the WPF engine that draws window content, fires keyboard and mouse events and does a lot of other things. The only way I know of to intercept messages is to install HwndSourceHook with a delegate to our functions. The following code shows how to manage a WM_NCLBUTTONDOWN message:

Share

About the Author

I bought my first computer in Nov 1991, 21th and I started programming with QBasic under MSDOS.
Today my main interest is developping application with .NET 3.5.
Visit YouDev.net for tutorials on AvalonDock, download WPF controls, samples and code.

I have the same problem,and then I resolve it.the reason is the doumentPane class,in it's Resources define a controlTemplate,but in not work well on Net4.0, especially two buttons' style ,in the end I separat the ScrollViewer's template in a style and define in the doumentsPane's Resource.

Most of us speak English here so I assume since you read the article and have an opinion you can respond in English; even if it isn't too good we would appriciate the effort. I did try to translate your response which I think is Turkish and the best I can do is "mode to the floors in the e code vundi".

hello
when I want to dock dockablecontent in the center(just in the center) of dockmanager an error raise:
object reference not set to an instance of an object
note: I use VS2010.
what can I do to solve this?

i'm building a timetable application and for a few days now i've been looking for a dock manager to fulfill my needs. there are some extremely nice ones on the web but they cost money. your solution is just as great for my needs.
thanks a lot.

Hey there Adolfo its Sacha Barber here, your company AqiStar, asked me to confirm my email with you via codeproject in reagrds to a query I have sent in via an email, see your info@aqistar.com, administrator, who needed my details confirmed.

So this is me confirming them, could you let them know I confirmed my details with you here.

Sacha Barber

Microsoft Visual C# MVP 2008/2009

Codeproject MVP 2008/2009

Your best friend is you.
I'm my best friend too. We share the same views, and hardly ever argue

Hello!
I have some documents in DockingLibrary.DocumentContent. Each document has a Viewport3D with lights and a camera.
I need to change the camera configuration within the ACTIVE document.
How can I get the active document in the collection?

AvalonDock is a WPF controls library which can be used to create a docking layout system as present in Visual Studio. It supports fly-out panes, floating windows, multiple docking managers in the same window, styles and themes. It can also host WinForms controls.

But, it does not work. The menu items are not enabled when text is selected in a control inside an inner pane. This seems like a problem with the Focus Manager (and I think it occurs because ManagedContent inherits from Window, which handles its own keyboard focus events).

If I put the Menu items insider the Dockable window, they work as expected.

I'm triing to show dockablecontent, that is not shown yet, as floating during application runtime.
I get a string by dockManager.GetLayoutAsXml() and make necessary changes.
Then use dockManager.RestoreLayoutFromXml() method to show windows.
They are shown.
But as I click on their titles and try to move them(to dock), the InvalidOperationException ("This Visual is not connected to a PresentationSource.") is thrown.

I had the similar issue with getting this exception.
I subscribed on SelectedChanged event of tab control which is
does not mean that the selection changed in WPF.
See http://dotbay.blogspot.com/2009/10/in-wpf-selectionchanged-does-not-mean.html
or http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/6c89846b-9d3b-48d7-be4e-bc202c03094d/
for more details. Hope, this will help you.
Alex.

1. Avalon doesn't change it's state from floating to, for example, docking when you click on its
title and chose floating from context menu.
2. The docking menu item has to be enabled and floating disabled when the window is floating.
More, menu must have TabDocument and Close (and, maybe, Docking and Floating, but better if not) items at Floating state of window, if you have Floating, Tabbed, AutoHide, Close at Docking.
3. Sometimes context menu items are disabled at AutoHide state and sometimes are enabled.

I think it's better, when all item are in context menu and enabled. When user chooses state at which windows is, windows state changes to previous; when Docking or AutoHide it docks to side, where it was at last or to default(right); same thing about Tabbed.

Here some explanations:
1. A floating windows has two states: Floating and Dockable. If click Floating menu item from context menu which appears when you click on floating window title you select the Floating state, otherwise if you click Dockable menu item you select the Dockable state. When a floating window is in Floating state you cannot redock the window contents to the original docking manager, this means that if you move the window the docking manager doesn't show the anchor icons. (as happens in VS)
2/3. Context menu on a pane when is in AutoHide state has not the right enabled/disabled states because the OnCanExecute handlers are not properly compiled at this time, even if the commands like FloatingWindow have no effect. This issue will be fixed in next release.

Regarding the option to mantains all the context menus enabled, I disagree. In my opinion commands should be enabled/visible only if commands have effect in that context.

For further discussions on AvalonDock please use the discussion section on CodePlex site, and to report a bug like point 3 use the issue tracker section. In this way other users of the library can see the problems and you can ckeck if the bug has been fixed in a particular release.

At the moment the only informations you can get on AvalonDock is throught its web site at www.codeplex.com/avalondock. Anyway i'm working on a sample dimostrating video which I'll post together with version 1.1, that is almost completed.

Hi!
I've a problem with the DockingLibrary.
The trouble happens as I change "Tabbed document", "Auto hide", etc in lines 244 - 247 into russian.
The exception is "invalid character in the given encoding. Line ...".
Could anyone help me, please?

First of all, thank you for this very useful library.
I am currently trying to relocate and resize the different pane based on some user preferences so user can come back to a predefined display without having resize and move all the window one by one.
But every time I can't find on which object I should apply my sizing changes.
Have you any suggestion ?