在WPF中实现多坞窗口系统(例如Blend,Visual Studio) [英] Implementing a multidock window system (like blend, visual studio) in WPF
问题描述
您将如何实现对接工具箱窗口系统,如Expression Blend中所示,您可以在其中以多种方式彼此对接地对接工具箱窗口,即作为选项卡或作为浮动顶层窗口重叠.我的系统的行为应与Expression Blend中的行为几乎相同.同样,我获得视觉提示的方式也正是我需要的,在拖动时工具箱窗口将停靠在该位置.
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.
还请注意,由于内部政策的原因,我不能为此使用任何开放源代码或第三方库.
我会对您如何设置此类通用课程设计感兴趣?我希望保持通用性,以便可以将其用于许多不同的情况.
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:
替代文本http://img196.imageshack.us/img196/2450/dockingregions. png
通常,我在这里面临市长的问题:如何设计编程模型(如何在XAML中保留对接配置)以及如何从根本上实现基础功能.我的第一个强项就是我想成为DockPanel和TabControl的共生者.与此类似:
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>
当然,这还没有意义.无法以这种方式定义对接,并且此处尚未解决开窗问题.但是我喜欢仅通过在DockTabItem上定义一些属性来定义停靠和选项卡组的想法.我真的不想引入额外的控件,例如TabGroups或类似的控件.我仅通过定义子项和Dock附加属性的顺序就喜欢DockPanel中的停靠行为.当然,我的停靠会更复杂一些,并且表现得更像Grid.
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.
推荐答案
为支持您在问题中说明的场景,单个DockPanel
就足够了,因此您只需要编写OnDragEnter,OnDragOver,OnDragLeave和OnDragDrop.我通常使用单个事件处理程序,因为这四个事件的处理是如此相似:
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:
OnDragEnter & OnDragOver:
- 计算将要放置的物品在DockPanel中的哪个边缘和哪个位置
- 删除现有的装饰者
- 添加矩形装饰物以显示放置位置
OnDragLeave:
OnDragLeave:
- 删除现有的装饰器
OnDragDrop:
OnDragDrop:
- 删除现有的装饰者
- 计算将要放置的物品在DockPanel中的哪个边缘和哪个位置
- 从当前面板中删除拖动的项目,在其上设置DockPanel.Dock,然后将其添加到新面板中
自然,您还必须处理标题栏上的拖动并在源对象上调用DoDragDrop.
Naturally you also have to handle dragging on the title bar and call DoDragDrop on the source object.
这里的两个复杂性是:
- 确定DockPanel是否足以满足您的需求,或者是否需要更复杂的数据结构
- 确保几何计算考虑到所有可能的窗口配置
对于一个简单的算法,我估计需要花一周的时间才能消除所有皱纹.如果您需要一个非常复杂的数据结构并且该结构本身并不明显,那么可能需要花费大量时间才能弄清该部分.
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.
这篇关于在WPF中实现多坞窗口系统(例如Blend,Visual Studio)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!