在 WPF 中实现多停靠窗口系统(如 Blend、Visual Studio)
您将如何实现如 Expression Blend 中所示的停靠工具箱窗口系统,您可以通过多种方式相互停靠工具箱窗口,如选项卡或浮动顶级窗口一样重叠。我的系统的行为应该与 Expression Blend 中的行为几乎相同。另外,我在拖动时获得工具箱窗口停靠位置的视觉提示的方式正是我所需要的。
只有一个例外:在混合中,当拖动到已经是顶层(撕掉)的工具箱窗口时,我只能将其停靠为填充整个窗口的选项卡。然而,我需要一个工具箱窗口和主窗口之间没有区别的系统。我需要能够将工具箱窗口中的窗口停靠在彼此下方,就像在主窗口中一样。
另请注意,由于内部政策,我不能为此使用任何开源或第 3 方库。
我对您如何为此类内容设置通用类设计感兴趣?我希望尽可能保持通用,以便它可以用于许多不同的场景。
对接行为如下图所示。中心图像显示了感应拖动停靠区域。以及窗口将捕捉的外部图像:
alt text http://img196.imageshack.us /img196/2450/dockingregions.png
一般来说,我在这里面临主要问题:如何设计编程模型(如何在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>
当然这还没有意义。无法以这种方式定义对接,并且此处尚未解决窗口问题。但我喜欢仅通过在 DockTabItem 上定义一些属性来定义对接和选项卡组的想法。我真的不想引入像 TabGroups 或类似的额外控件。我喜欢 DockPanel 中的停靠行为,只需定义子级的顺序和 Dock 附加属性即可。当然,我的对接会更复杂一些,并且行为更像网格的行为。
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 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:
<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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为了支持您在问题中说明的场景,单个
DockPanel
就足够了,因此您需要编写的只是 OnDragEnter、OnDragOver、OnDragLeave 和 OnDragDrop 的处理程序。我通常使用单个事件处理程序,因为这四个事件的处理非常相似:OnDragEnter 和 OnDragEnter 。 OnDragOver:
OnDragLeave:
OnDragDrop:
当然,您还必须处理标题栏上的拖动并在源对象上调用 DoDragDrop。
这里的两个复杂性是:
对于一个简单的算法,我估计需要一周的时间消除所有皱纹。如果您需要一个非常复杂的数据结构,并且该结构本身并不明显,那么可能需要花费大量时间来弄清楚该部分。
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:
OnDragLeave:
OnDragDrop:
Naturally you also have to handle dragging on the title bar and call DoDragDrop on the source object.
The two complexities here are:
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.
有人在 codeproject.com 上发布了一个很棒的 WPF 对接库,它具有您正在寻找的功能。
我自己用过一次,用起来还算顺利。
在这里查看:http://www.codeproject.com/KB/WPF/WPFdockinglib .aspx
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
阿瓦隆码头很好。
https://github.com/Dirkster99/AvalonDock
遗憾的是你不能使用它;)
AvalonDock is good.
https://github.com/Dirkster99/AvalonDock
It's a pity you can't use it ;)
WPF 已经具有支持停靠(或该效果)的控件。查看 Adam Nathan 的 WPF 书籍 WPF Unleashed,他在第 2 部分中介绍了它。
WPF already has controls which support docking (or that effect). Check Adam Nathan's WPF book WPF Unleashed, he covers it in part 2.