在WPF中实现一个multidock窗口系统(如blend,visual studio)

你将如何实现一个对接工具箱窗口系统,如Expression Blend中所看到的那样,你可以通过很多方式对接工具箱窗口,重叠为标签页或浮动顶层窗口。 我的系统的performance应该和Expression Blend差不多。 另外,我得到的视觉线索拖动工具箱窗口停靠的地方正是我所需要的。

只有一个例外:在拖放到已经是顶层的工具箱窗口(撕掉)时,在混合时,我只能将它作为填充整个窗口的选项卡。 然而,我需要一个系统,在工具箱窗口和主窗口之间没有区别。 我需要能够将窗口放置在工具箱窗口中,就像在主窗口中一样。

另外请注意,由于内部政策,我不能使用任何开放源码或第三方库。

我会对如何设置类似这样的一般类devise感兴趣? 我想保持尽可能通用,所以它可以用于很多不同的场景。

停靠行为如下图所示。 中心图像显示了感应式拖拽区域。 而窗口将捕捉的外部图像:

替代文字http://img196.imageshack.us/img196/2450/dockingregions.png

一般来说,我面临着市长问题:我如何devise编程模型(如何在XAML中保持对接configuration),以及如何实现底层function。 我的第一个尝试是我想要一个DockPanel和一个TabControl的共生。 有些事情是这样的:

<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> 

当然这还没有意义。 停靠不能这样定义,窗口问题在这里还没有被提到。 但是我喜欢通过在DockTabItem上定义一些属性来定义对接和选项卡组的想法。 我真的不想引入像TabGroups或类似的额外控制。 我喜欢DockPanel中的对接行为,只需定义子对象的顺序和Dock附属属性即可。 当然,我的对接会更复杂一些,performance得更像网格。

为了支持你在你的问题中演示的场景,一个DockPanel就足够了,所以你需要写的是处理OnDragEnter,OnDragOver,OnDragLeave和OnDragDrop。 我通常使用一个事件处理程序,因为处理这四个事件是如此相似:

OnDragEnter&OnDragOver:

  1. 计算DockPanel中的哪条边和哪个位置
  2. 删除任何现有的装饰者
  3. 添加矩形装饰物以显示放置位置

OnDragLeave:

  1. 删除任何现有的装饰者

OnDragDrop:

  1. 删除任何现有的装饰者
  2. 计算DockPanel中的哪条边和哪个位置
  3. 从当前面板中删除拖动项目,设置DockPanel.Dock,并将其添加到新面板

当然,你也必须处理标题栏上的拖动,并在源对象上调用DoDragDrop。

这两个复杂性是:

  • 决定DockPanel是否足够满足您的需求,或者您需要更复杂的数据结构
  • 确保几何计算考虑到所有可能的窗口配置

对于一个简单的算法,我估计需要一个星期才能弄清楚所有的皱纹。 如果你需要一个非常复杂的数据结构,而且结构本身并不明显,那么可能需要花费很长的时间才能找出结果。

在codeproject.com上发布了一个很棒的WPF Docking Library,它有你正在寻找的功能。 我曾经使用它myslef,我很顺利。

看看这里: http : //www.codeproject.com/KB/WPF/WPFdockinglib.aspx

AvalonDock很好。

http://avalondock.codeplex.com/

很遗憾你不能使用它;)

WPF已经有支持对接的控件(或者那个效果)。 检查亚当Nathan的WPF书WPF释放 ,他在第2部分涵盖它。