防止对接AvalonDock

时间:2015-04-19 18:54:06

标签: c# wpf avalondock

是否可以通过一些过滤来防止将一个可锚定元素对接到另一个可锚定元素?例如,在viewmodel中,我可以包含一些属性doctype。对于一个可锚定元素,doctype的值将是“a”,而另一个“b”的值。如果值为“a”的可锚定元素无法与doctype“b”对接到可锚定元素,我如何使用属性doctype来阻止对接?也许,还有其他解决方案。

3 个答案:

答案 0 :(得分:0)

我在LayoutAnchorableFloatingWindowControl.cs上更改了IOverlayWindowHost.GetDropAreas方法

第一步是初始化内容类型。

var floatingWindowContentHost = Content as FloatingWindowContentHost;
if (floatingWindowContentHost == null) return _dropAreas;
var rootVisual = floatingWindowContentHost.RootVisual;
Type type = null;

var layoutAnchorableFloatingWindow = draggingWindow.Model as LayoutAnchorableFloatingWindow;
if (layoutAnchorableFloatingWindow != null)
{
    //big part of code for getting type
    var layoutAnchorablePane = layoutAnchorableFloatingWindow.SinglePane as LayoutAnchorablePane;

    if (layoutAnchorablePane != null
        && (layoutAnchorableFloatingWindow.IsSinglePane
        && layoutAnchorablePane.SelectedContent != null))
    {
        var layoutAnchorable = ((LayoutAnchorablePane)layoutAnchorableFloatingWindow.SinglePane).SelectedContent as LayoutAnchorable;
        if (layoutAnchorable != null)
            type = layoutAnchorable.Content;
    }
    else
    {
        var pane = GetLayoutAnchorablePane(layoutAnchorableFloatingWindow.RootPanel);
        if (pane == null || pane.SelectedContent == null) 
            return null;

        var layoutAnchorable = pane.SelectedContent as LayoutAnchorable;
        if (layoutAnchorable != null)
            type = layoutAnchorable.Content;
    }
}

在此之后,我只需比较两种类型,并将其放入_dropAreas

foreach (var areaHost in rootVisual.FindVisualChildren<LayoutAnchorablePaneControl>())
{
    Type areahostType = null;
    var layoutAnchorablePane = areaHost.Model as LayoutAnchorablePane;
    if (layoutAnchorablePane != null && layoutAnchorablePane.SelectedContent != null)
    {
        var layoutAnchorable = ((LayoutAnchorablePane)areaHost.Model).SelectedContent as LayoutAnchorable;
        if (layoutAnchorable != null)
            areahostType = layoutAnchorable.Content;
    }
    // prevent docking different documents
    if (type != null && areahostType != null && areahostType == type)
    {
        _dropAreas.Add(new DropArea<LayoutAnchorablePaneControl>( areaHost, DropAreaType.AnchorablePane));
    }
}

要防止停靠到文档区域,需要在DockingManager.cs上对同一方法进行更改

为了防止DropTargets需要更改OverlayWindow.cs

答案 1 :(得分:0)

改变IOverlayWindowHost.GetDropAreas是正确的,但这种改变对我来说似乎要容易得多。

我在“LayoutAnchorableFloatingWindowControl.cs”中简单地删除了这个foreach:

...
// Remove this foreach
foreach (var areaHost in rootVisual.FindVisualChildren<LayoutDocumentPaneControl>())
{
    _dropAreas.Add(new DropArea<LayoutDocumentPaneControl>(
        areaHost,
        DropAreaType.DocumentPane));
}

return _dropAreas;

并且在“DockingManager.cs”中的其他实现中,您必须添加其他原因:

if (!isDraggingDocuments)
{
    _areas.Add(new DropArea<DockingManager>(
        this,
        DropAreaType.DockingManager));

    foreach (var areaHost in this.FindVisualChildren<LayoutAnchorablePaneControl>())
    {
        if (areaHost.Model.Descendents().Any())
        {
            _areas.Add(new DropArea<LayoutAnchorablePaneControl>(
                areaHost,
                DropAreaType.AnchorablePane));
        }
    }
}
// -----> This else is new
else
{ 
    foreach (var areaHost in this.FindVisualChildren<LayoutDocumentPaneControl>())
    {
        _areas.Add(new DropArea<LayoutDocumentPaneControl>(
            areaHost,
            DropAreaType.DocumentPane));
    }

    foreach (var areaHost in this.FindVisualChildren<LayoutDocumentPaneGroupControl>())
    {
        var documentGroupModel = areaHost.Model as LayoutDocumentPaneGroup;
        if (documentGroupModel.Children.Where(c => c.IsVisible).Count() == 0)
        {
            _areas.Add(new DropArea<LayoutDocumentPaneGroupControl>(
                areaHost,
                DropAreaType.DocumentPaneGroup));
        }
    }
}

return _areas;

因此,如果您没有拖动LayoutDocument,请不要将文档窗格控件添加到放置区域。

多数民众赞成 - 适合我。

答案 2 :(得分:0)

在AvalonDock 3.5(我认为从3.2开始)中,有一个LayoutAnchorable属性CanDockAsTabbedDocument,可以将其设置为false以防止工具窗口停靠在DocumentPane中。这仅适用于AvalonDock 3.8 and earlier中的上下文菜单,而拖放行为仍然有问题。

但是您可以使用此修复程序来获得AvalonDock 3.5的预期拖放行为。 以下代码扩展了IOverlayWindowHost.GetDropAreas中的DockingManager.cs

此解决方案的关键是dockAsDocument布尔变量。它保护 foreach 循环,该循环负责将任何项目插入DocumentsPane的{​​{1}}中。

MainWindow内可以找到一个dockAsDocument变量并将其配置为LayoutAnchorable时,LayoutFloatingWindowControl变量将设置为false。 / p>

CanDockAsTabbedDocument="False"