views:

662

answers:

3

How would you go about to implement a docking toolbox windowing system as seen in Expression Blend where you can dock toolbox windows in a lot of ways beneat each other, overlapping as tabs or as floating top level windows. My system should behave pretty much the same as in Expression Blend. Also the way I get visual cues where the toolbox window would dock when dragging is exactly what I need.

There is just one exeception: In blend when dragging onto a toolbox window that is already top level (torn off) I can only dock it as a tab filling the whole window. I however need a system where there is no difference between a toolbox window and the main window. I need to be able to dock the windows beneath each other in a toolbox window just as in the main window.

Also note that due to an internal policy I can not use any open source or 3rd party library for this.

I'd be interested in how you would setup the general class design for something like this? I would like to stay as generic as possible so it can be used for lot of different scenarios.

The dockeing behavior is as in the following picture. The center image shows the sensetive drag docking region. And the outer images where the window would snap:

alt text

Generally I am facing to mayor problems here: How do I design the programming model (how are the docking configurations to be persisted in XAML) and how do I acutally implement the underlying functionality. My first tought would be that I'd like to habe a symbiosis of a DockPanel and a TabControl. Something in the lines of this:

<DockTabControl>
  <DockTabItem Dock="FirstLeft">
    <DockTabItem.Header>
        <TextBlock>Tab 1</TextBlock>
    </DockTabItem.Header>
    <!-- Tab 1 content -->
  </DockTabItem>
  <DockTabItem Header="Tab 2" Dock="SecondLeft" DockMode="MergeWithPreviousToTabgroup">
    <!-- Tab 2 content -->
  </DockTabItem>
  <DockTabItem Header="Tab 3" Dock="FirstMiddle">
    <!-- Tab 3 content -->
  </DockTabItem>
</DockTabControl>

Of course this doesn't make sense yet. Docking can't be defined that way and the windowing problem is not adressed here yet. But I like the idea of defining the docking and the tabgroups just by defining some properties on the DockTabItem. I really wouldn't want to introduce extra controls like TabGroups or similar. I like how the docking behavior in the DockPanel just by defining the order of the children and the Dock attached property. Of course my docking will be a bit more complex and behaves more like what the Grid does.

A: 

WPF already has controls which support docking (or that effect). Check Adam Nathan's WPF book WPF Unleashed, he covers it in part 2.

Larry Osterman
the wpf docking control does not allow the **end user** to control the docking as it does not provide a UI to move docked windows etc.
Ian Ringrose
In chapter 6 Adam has an example titled "Putting It All Together: Creating a Visual Studio-Like Collapsible, Dockable, Resizable Pane". That appears to be exactly what bitbonk asked for.
Larry Osterman
Adam's example does not actually allow you to reorganize the windows' docking which is what I think bitbonk is asking for. All Adam's example allows you to do is resize and hide/display two hard-coded panes that are always docked to the same side of the window. No drag and drop or reorganizing of panes is included.
Ray Burns
+3  A: 

To support the scenarios you illustrate in your question a single DockPanel would suffice, so all you need to write is handlers for OnDragEnter, OnDragOver, OnDragLeave, and OnDragDrop. I generally use a single event handler because the handling of these four events is so similar:

OnDragEnter & OnDragOver:

  1. Compute which edge and which location in DockPanel the item will be dropped
  2. Remove any existing adorner
  3. Add rectangular adorner to show drop location

OnDragLeave:

  1. Remove any existing adorner

OnDragDrop:

  1. Remove any existing adorner
  2. Compute which edge and which location in DockPanel the item will be dropped
  3. Remove dragged item from current panel, set DockPanel.Dock on it, and add it to new panel

Naturally you also have to handle dragging on the title bar and call DoDragDrop on the source object.

The two complexities here are:

  • Deciding whether a DockPanel is sufficient for your needs or if you will need a more complex data structure
  • Making sure the geometric calculations take into account all possible configurations of windows

For a simple algorithm I would estimate it would take a week to get all the wrinkles ironed out. If you need a really complex data structure and the structure itself is unobvious, it could take serious time to figure that part out.

Ray Burns
I didn't like seeing this answer downvoted, because it really does describe some of the beginning pieces to a self-built solution (along with a number of other things, like `Adorner`s).
Joel B Fant
+4  A: 

There's a great WPF Docking Library someone has published on codeproject.com, that has the functionality you're looking for. I used it myslef once, and i got it going pretty smoothly.

Check it out here : http://www.codeproject.com/KB/WPF/WPFdockinglib.aspx

gillyb
As I already mentioned I can use anything that is not written be me? Now I am not even sure if I can't even look at how others implemented it to avoid (unintentionally) stealing ideas or implementation details.
bitbonk
The docking library seems like the best bet to view and write your code. If you're just reviewing how it was implemented, there are probably no issues with "stealing". An **idea** can't be copyrighted - only a particular implementation of the idea. Review this and the other recommendations on this page and then come up with your own way of doing it.
Otaku
@bitbonk: But you are allowed to ask questions in stack overflow and get ideas or implementation details from unknown people?
Vinko Vrsalovic
@Vinko No one can sue me for that. :)
bitbonk
@bitbonk: Oh, but they can. They winning is another matter :)
Vinko Vrsalovic