在 WPF 中实现多停靠窗口系统(如混合、视觉工作室)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2247402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implementing a multidock window system (like blend, visual studio) in WPF
提问by bitbonk
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.
您将如何实现一个停靠工具箱窗口系统,如 Expression Blend 中所见,您可以在其中以多种方式停靠工具箱窗口,这些方式彼此友好,重叠为选项卡或浮动顶级窗口。我的系统的行为应该与 Expression Blend 中的几乎相同。此外,我在拖动时获得工具箱窗口停靠位置的视觉提示的方式正是我所需要的。
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.
另请注意,由于内部政策,我不能为此使用任何开源或 3rd 方库。
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 http://img196.imageshack.us/img196/2450/dockingregions.png
替代文字 http://img196.imageshack.us/img196/2450/dockingregions.png
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:
一般来说,我在这里面临着主要问题:我如何设计编程模型(如何在 XAML 中持久化对接配置)以及如何真正实现底层功能。我的第一个想法是我想要一个 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>
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.
当然,这还没有意义。不能以这种方式定义对接,并且这里还没有解决窗口问题。但我喜欢通过在 DockTabItem 上定义一些属性来定义停靠和选项卡组的想法。我真的不想引入像 TabGroups 或类似的额外控件。我喜欢 DockPanel 中的停靠行为如何仅仅通过定义子项的顺序和 Dock 附加属性。当然,我的对接会更复杂一些,并且表现得更像网格所做的那样。
回答by Ray Burns
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:
为了支持您在问题中说明的场景,一个DockPanel
就足够了,因此您需要编写的只是 OnDragEnter、OnDragOver、OnDragLeave 和 OnDragDrop 的处理程序。我通常使用单个事件处理程序,因为这四个事件的处理非常相似:
OnDragEnter & OnDragOver:
OnDragEnter 和 OnDragOver:
- Compute which edge and which location in DockPanel the item will be dropped
- Remove any existing adorner
- Add rectangular adorner to show drop location
- 计算项目将被丢弃的 DockPanel 中的哪个边缘和哪个位置
- 删除任何现有的装饰器
- 添加矩形装饰器以显示放置位置
OnDragLeave:
OnDragLeave:
- Remove any existing adorner
- 删除任何现有的装饰器
OnDragDrop:
拖放:
- Remove any existing adorner
- Compute which edge and which location in DockPanel the item will be dropped
- Remove dragged item from current panel, set DockPanel.Dock on it, and add it to new panel
- 删除任何现有的装饰器
- 计算项目将被丢弃的 DockPanel 中的哪个边缘和哪个位置
- 从当前面板移除拖动的项目,在其上设置 DockPanel.Dock,并将其添加到新面板
Naturally you also have to handle dragging on the title bar and call DoDragDrop on the source object.
当然,您还必须处理标题栏上的拖动并在源对象上调用 DoDragDrop。
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
- 确定 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.
对于一个简单的算法,我估计需要一周时间才能消除所有皱纹。如果您需要一个非常复杂的数据结构,而结构本身并不明显,则可能需要花费大量时间才能弄清楚该部分。
回答by gillyb
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.
有人在 codeproject.com 上发布了一个很棒的 WPF Docking Library,它具有您正在寻找的功能。我自己用过一次,我用起来很顺利。
Check it out here : http://www.codeproject.com/KB/WPF/WPFdockinglib.aspx
回答by Ashley Davis
AvalonDock is good.
AvalonDock 很好。
http://avalondock.codeplex.com/
http://avalondock.codeplex.com/
It's a pity you can't use it ;)
很遗憾你不能使用它;)
回答by ReinstateMonica Larry Osterman
WPF already has controls which support docking (or that effect). Check Adam Nathan's WPF book WPF Unleashed, he covers it in part 2.
WPF 已经有支持停靠(或那种效果)的控件。查看 Adam Nathan 的 WPF 书籍WPF Unleashed,他在第 2 部分中介绍了它。