From 23482a35b8a487208084b5329d99239f84db56cc Mon Sep 17 00:00:00 2001
From: amolf-se <56731291+amolf-se@users.noreply.github.com>
Date: Mon, 28 Oct 2019 12:04:45 +0100
Subject: [PATCH 1/5] Changes from SVN 35121: Added property changed event
handler to set the SelectedIndex of the TabControl to the
selectedContentIndex of the pane model. This will cause the tabcontrol do
switch to the correct panel when IsActive is set.
---
.../Controls/LayoutDocumentPaneControl.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
index ec687db8..0f99da0b 100644
--- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
+++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
@@ -48,6 +48,14 @@ internal LayoutDocumentPaneControl( LayoutDocumentPane model )
SetBinding( ItemsSourceProperty, new Binding( "Model.Children" ) { Source = this } );
SetBinding( FlowDirectionProperty, new Binding( "Model.Root.Manager.FlowDirection" ) { Source = this } );
+ model.PropertyChanged += (o, e) =>
+ {
+ if (e.PropertyName == nameof(model.SelectedContentIndex))
+ {
+ SelectedIndex = _model.SelectedContentIndex;
+ }
+ };
+
// Handle SizeChanged event instead of LayoutUpdated. It will exlude fluctuations of Actual size values.
// this.LayoutUpdated += new EventHandler( OnLayoutUpdated );
this.SizeChanged += OnSizeChanged;
From d2d4467f49787faab6bde04b99867c5a43c16918 Mon Sep 17 00:00:00 2001
From: amolf-se <56731291+amolf-se@users.noreply.github.com>
Date: Tue, 29 Oct 2019 09:18:50 +0100
Subject: [PATCH 2/5] Changed to SVN rev 41162. Dock document in floating
window. Todo: check undock last document.
---
.../Theme.xaml | 6 +-
.../Theme.xaml | 6 +-
.../Theme.xaml | 6 +-
.../Theme.xaml | 6 +-
.../Themes/Generic.xaml | 6 +-
.../Controls/AnchorablePaneDropTarget.cs | 5 -
.../Controls/DocumentPaneDropTarget.cs | 388 +++++++++---------
.../Controls/DocumentPaneGroupDropTarget.cs | 4 +-
.../Controls/DragService.cs | 1 +
.../LayoutDocumentFloatingWindowControl.cs | 267 ++++++++++--
.../Controls/LayoutDocumentPaneControl.cs | 25 --
.../Xceed.Wpf.AvalonDock/DockingManager.cs | 19 +-
.../Layout/LayoutDocumentFloatingWindow.cs | 146 +++++--
.../Layout/LayoutDocumentPane.cs | 132 +++---
.../Xceed.Wpf.AvalonDock/Layout/LayoutRoot.cs | 15 +
.../Xceed.Wpf.AvalonDock/Themes/generic.xaml | 25 +-
16 files changed, 688 insertions(+), 369 deletions(-)
diff --git a/source/Components/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml b/source/Components/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml
index 665ff718..c21193ea 100644
--- a/source/Components/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml
+++ b/source/Components/Xceed.Wpf.AvalonDock.Themes.Aero/Theme.xaml
@@ -1343,7 +1343,7 @@
-
@@ -1358,7 +1358,7 @@
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
DropDownContextMenu="{Binding Model.Root.Manager.DocumentContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
- DropDownContextMenuDataContext="{Binding Path=RootDocumentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
+ DropDownContextMenuDataContext="{Binding Path=SingleContentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_CxMenu_Hint}">
-
@@ -914,7 +914,7 @@
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
DropDownContextMenu="{Binding Model.Root.Manager.DocumentContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
- DropDownContextMenuDataContext="{Binding Path=RootDocumentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
+ DropDownContextMenuDataContext="{Binding Path=SingleContentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_CxMenu_Hint}">
@@ -951,7 +951,7 @@
Focusable="False"
Style="{StaticResource AvalonDock_Expression_ButtonStyle}"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
- Command="{Binding Path=RootDocumentLayoutItem.CloseCommand, RelativeSource={RelativeSource TemplatedParent}}"
+ Command="{Binding Path=SingleContentLayoutItem.CloseCommand, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_Close}"
Grid.Column="3">
diff --git a/source/Components/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml b/source/Components/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml
index ac3a1a05..8321164c 100644
--- a/source/Components/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml
+++ b/source/Components/Xceed.Wpf.AvalonDock.Themes.Metro/Theme.xaml
@@ -1401,7 +1401,7 @@
-
@@ -1416,7 +1416,7 @@
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
DropDownContextMenu="{Binding Model.Root.Manager.DocumentContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
- DropDownContextMenuDataContext="{Binding Path=RootDocumentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
+ DropDownContextMenuDataContext="{Binding Path=SingleContentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_CxMenu_Hint}">
-
@@ -1498,7 +1498,7 @@
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
DropDownContextMenu="{Binding Model.Root.Manager.DocumentContextMenu, RelativeSource={RelativeSource TemplatedParent}}"
- DropDownContextMenuDataContext="{Binding Path=RootDocumentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
+ DropDownContextMenuDataContext="{Binding Path=SingleContentLayoutItem, RelativeSource={RelativeSource TemplatedParent}}"
ToolTip="{x:Static avalonDockProperties:Resources.Document_CxMenu_Hint}">
- ().FirstOrDefault();
+
+ switch (Type)
+ {
+ case DropTargetType.DocumentPaneDockBottom:
+ #region DropTargetType.DocumentPaneDockBottom
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
+
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
+ {
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + 1 + i, documentsToMove[i]);
+ }
+ else
+ parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
+ {
+ Orientation = System.Windows.Controls.Orientation.Vertical,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Add(floatingWindow.RootPanel);
+
+ }
+ }
+ break;
+ #endregion
+ case DropTargetType.DocumentPaneDockTop:
+ #region DropTargetType.DocumentPaneDockTop
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
+
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
+ {
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + i, documentsToMove[i]);
+ }
+ else
+ parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
+ {
+ Orientation = System.Windows.Controls.Orientation.Vertical,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ //the floating window must be added after the target modal as it could be raise a CollectGarbage call
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
+
+ }
+ }
+ break;
+ #endregion
+ case DropTargetType.DocumentPaneDockLeft:
+ #region DropTargetType.DocumentPaneDockLeft
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
+
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
+ {
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + i, documentsToMove[i]);
+ }
+ else
+ parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
+ {
+ Orientation = System.Windows.Controls.Orientation.Horizontal,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ //the floating window must be added after the target modal as it could be raise a CollectGarbage call
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
+
+ }
+ }
+ break;
+ #endregion
+ case DropTargetType.DocumentPaneDockRight:
+ #region DropTargetType.DocumentPaneDockRight
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
+
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
+ {
+ var documentToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + 1 + i, documentToMove[i]);
+ }
+ else
+ parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
+ {
+ Orientation = System.Windows.Controls.Orientation.Horizontal,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Add(floatingWindow.RootPanel);
+
+ }
+ }
+ break;
+ #endregion
+
+ case DropTargetType.DocumentPaneDockInside:
+ #region DropTargetType.DocumentPaneDockInside
+ {
+ var paneModel = targetModel as LayoutDocumentPane;
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+
+ int i = _tabIndex == -1 ? 0 : _tabIndex;
+ foreach (var anchorableToImport in
+ layoutDocumentPaneGroup.Descendents().OfType().ToArray())
+ {
+ paneModel.Children.Insert(i, anchorableToImport);
+ i++;
+ }
+ }
+ break;
+ #endregion
+ }
+
+ documentActive.IsActive = true;
+
+ base.Drop(floatingWindow);
+ }
protected override void Drop( LayoutAnchorableFloatingWindow floatingWindow )
{
diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
index b9e3c999..97996682 100644
--- a/source/Components/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
+++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
@@ -51,8 +51,8 @@ protected override void Drop( LayoutDocumentFloatingWindow floatingWindow )
#region DropTargetType.DocumentPaneGroupDockInside
{
var paneGroupModel = targetModel as LayoutDocumentPaneGroup;
- var paneModel = paneGroupModel.Children[ 0 ] as LayoutDocumentPane;
- var sourceModel = floatingWindow.RootDocument;
+ var paneModel = paneGroupModel as LayoutDocumentPaneGroup;
+ var sourceModel = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
paneModel.Children.Insert( 0, sourceModel );
}
diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/DragService.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/DragService.cs
index 9676deca..e43cce14 100644
--- a/source/Components/Xceed.Wpf.AvalonDock/Controls/DragService.cs
+++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/DragService.cs
@@ -193,6 +193,7 @@ internal void Abort()
private void GetOverlayWindowHosts()
{
_overlayWindowHosts.AddRange( _manager.GetFloatingWindowsByZOrder().OfType().Where( fw => fw != _floatingWindow && fw.IsVisible ) );
+ _overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType().Where(fw => fw != _floatingWindow && fw.IsVisible));
_overlayWindowHosts.Add( _manager );
}
diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
index dceea960..558cf800 100644
--- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
+++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
@@ -15,14 +15,18 @@ This program is provided to you under the terms of the Microsoft Public
***********************************************************************************/
using System;
+using System.Collections.Generic;
+using System.Linq;
using Xceed.Wpf.AvalonDock.Layout;
using System.Windows;
using System.Windows.Controls.Primitives;
+using System.Windows.Input;
using Microsoft.Windows.Shell;
+using Xceed.Wpf.AvalonDock.Commands;
namespace Xceed.Wpf.AvalonDock.Controls
{
- public class LayoutDocumentFloatingWindowControl : LayoutFloatingWindowControl
+ public class LayoutDocumentFloatingWindowControl : LayoutFloatingWindowControl, IOverlayWindowHost
{
#region Members
@@ -41,6 +45,7 @@ internal LayoutDocumentFloatingWindowControl( LayoutDocumentFloatingWindow model
: base( model, isContentImmutable )
{
_model = model;
+ HideWindowCommand = new RelayCommand((p) => OnExecuteHideWindowCommand(p), (p) => CanExecuteHideWindowCommand(p));
UpdateThemeResources();
}
@@ -53,13 +58,13 @@ internal LayoutDocumentFloatingWindowControl( LayoutDocumentFloatingWindow model
#region Properties
- public LayoutItem RootDocumentLayoutItem
- {
- get
- {
- return _model.Root.Manager.GetLayoutItemFromModel( _model.RootDocument );
- }
- }
+ //public LayoutItem RootDocumentLayoutItem
+ //{
+ // get
+ // {
+ // return _model.Root.Manager.GetLayoutItemFromModel( _model.RootPanel );
+ // }
+ //}
#endregion
@@ -73,22 +78,63 @@ public override ILayoutElement Model
}
}
+ #region SingleContentLayoutItem
+
+ ///
+ /// SingleContentLayoutItem Dependency Property
+ ///
+ public static readonly DependencyProperty SingleContentLayoutItemProperty =
+ DependencyProperty.Register("SingleContentLayoutItem", typeof(LayoutItem), typeof(LayoutDocumentFloatingWindowControl),
+ new FrameworkPropertyMetadata((LayoutItem)null,
+ new PropertyChangedCallback(OnSingleContentLayoutItemChanged)));
+
+ ///
+ /// Gets or sets the SingleContentLayoutItem property. This dependency property
+ /// indicates the layout item of the selected content when is shown a single anchorable pane.
+ ///
+ public LayoutItem SingleContentLayoutItem
+ {
+ get { return (LayoutItem)GetValue(SingleContentLayoutItemProperty); }
+ set { SetValue(SingleContentLayoutItemProperty, value); }
+ }
+
+ ///
+ /// Handles changes to the SingleContentLayoutItem property.
+ ///
+ private static void OnSingleContentLayoutItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((LayoutDocumentFloatingWindowControl)d).OnSingleContentLayoutItemChanged(e);
+ }
+
+ ///
+ /// Provides derived classes an opportunity to handle changes to the SingleContentLayoutItem property.
+ ///
+ protected virtual void OnSingleContentLayoutItemChanged(DependencyPropertyChangedEventArgs e)
+ {
+ }
+
+ #endregion
+
protected override void OnInitialized( EventArgs e )
{
base.OnInitialized( e );
- if( _model.RootDocument == null )
- {
- InternalClose();
- }
- else
- {
- var manager = _model.Root.Manager;
+ var manager = _model.Root.Manager;
- Content = manager.CreateUIElementForModel( _model.RootDocument );
+ Content = manager.CreateUIElementForModel(_model.RootPanel);
+ // TODO IsVisibleChanged
+ //SetBinding(SingleContentLayoutItemProperty, new Binding("Model.SinglePane.SelectedContent") { Source = this, Converter = new LayoutItemFromLayoutModelConverter() });
- _model.RootDocumentChanged += new EventHandler( _model_RootDocumentChanged );
- }
+ _model.RootPanel.ChildrenCollectionChanged += RootPanelOnChildrenCollectionChanged;
+ }
+
+ void _model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "RootPanel" &&
+ _model.RootPanel == null)
+ {
+ InternalClose();
+ }
}
protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
@@ -98,8 +144,8 @@ protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, In
case Win32Helper.WM_NCLBUTTONDOWN: //Left button down on title -> start dragging over docking manager
if( wParam.ToInt32() == Win32Helper.HT_CAPTION )
{
- if( _model.RootDocument != null )
- _model.RootDocument.IsActive = true;
+ _model.Descendents().OfType().First(p => p.ChildrenCount > 0 && p.SelectedContent != null).SelectedContent.IsActive = true;
+ handled = true;
}
break;
case Win32Helper.WM_NCRBUTTONUP:
@@ -113,7 +159,6 @@ protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, In
WindowChrome.GetWindowChrome( this ).ShowSystemMenu = false;
}
break;
-
}
return base.FilterMessage( hwnd, msg, wParam, lParam, ref handled );
@@ -122,46 +167,196 @@ protected override IntPtr FilterMessage( IntPtr hwnd, int msg, IntPtr wParam, In
protected override void OnClosed( EventArgs e )
{
var root = Model.Root;
- root.Manager.RemoveFloatingWindow( this );
- root.CollectGarbage();
+ root?.Manager.RemoveFloatingWindow( this );
+ root?.CollectGarbage();
+
+ if (_overlayWindow != null)
+ {
+ _overlayWindow.Close();
+ _overlayWindow = null;
+ }
base.OnClosed( e );
if( !CloseInitiatedByUser )
{
- root.FloatingWindows.Remove( _model );
+ root?.FloatingWindows.Remove( _model );
}
- _model.RootDocumentChanged -= new EventHandler( _model_RootDocumentChanged );
+ _model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(_model_PropertyChanged);
}
#endregion
#region Private Methods
- private void _model_RootDocumentChanged( object sender, EventArgs e )
+ private void RootPanelOnChildrenCollectionChanged(object sender, EventArgs e)
{
- if( _model.RootDocument == null )
- {
- InternalClose();
- }
+ if( _model.RootPanel.Children.Count == 0)
+ {
+ InternalClose();
+ }
}
private bool OpenContextMenu()
{
var ctxMenu = _model.Root.Manager.DocumentContextMenu;
- if( ctxMenu != null && RootDocumentLayoutItem != null )
+ if (ctxMenu != null && SingleContentLayoutItem != null)
{
- ctxMenu.PlacementTarget = null;
- ctxMenu.Placement = PlacementMode.MousePoint;
- ctxMenu.DataContext = RootDocumentLayoutItem;
- ctxMenu.IsOpen = true;
- return true;
+ ctxMenu.PlacementTarget = null;
+ ctxMenu.Placement = PlacementMode.MousePoint;
+ ctxMenu.DataContext = SingleContentLayoutItem;
+ ctxMenu.IsOpen = true;
+ return true;
}
return false;
}
+ protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
+ {
+ // TODO
+ if (CloseInitiatedByUser && !KeepContentVisibleOnClose)
+ {
+ e.Cancel = true;
+ //_model.Descendents().OfType().ToArray().ForEach((a) => a.Hide());
+ }
+
+ base.OnClosing(e);
+ }
+
+ bool IOverlayWindowHost.HitTest(Point dragPoint)
+ {
+ Rect detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor());
+ return detectionRect.Contains(dragPoint);
+ }
+
+ DockingManager IOverlayWindowHost.Manager
+ {
+ get { return _model.Root.Manager; }
+ }
+
+ OverlayWindow _overlayWindow = null;
+
+ void CreateOverlayWindow()
+ {
+ if (_overlayWindow == null)
+ _overlayWindow = new OverlayWindow(this);
+ Rect rectWindow = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor());
+ _overlayWindow.Left = rectWindow.Left;
+ _overlayWindow.Top = rectWindow.Top;
+ _overlayWindow.Width = rectWindow.Width;
+ _overlayWindow.Height = rectWindow.Height;
+ }
+
+ IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow)
+ {
+ CreateOverlayWindow();
+ _overlayWindow.Owner = draggingWindow;
+ _overlayWindow.EnableDropTargets();
+ _overlayWindow.Show();
+
+ return _overlayWindow;
+ }
+
+ public void HideOverlayWindow()
+ {
+ _dropAreas = null;
+ _overlayWindow.Owner = null;
+ _overlayWindow.HideDropTargets();
+ }
+
+ List _dropAreas = null;
+ public IEnumerable GetDropAreas(LayoutFloatingWindowControl draggingWindow)
+ {
+ if (_dropAreas != null)
+ return _dropAreas;
+
+ _dropAreas = new List();
+
+ var rootVisual = (Content as FloatingWindowContentHost).RootVisual;
+
+ foreach (var areaHost in rootVisual.FindVisualChildren())
+ {
+ _dropAreas.Add(new DropArea(
+ areaHost,
+ DropAreaType.AnchorablePane));
+ }
+ foreach (var areaHost in rootVisual.FindVisualChildren())
+ {
+ _dropAreas.Add(new DropArea(
+ areaHost,
+ DropAreaType.DocumentPane));
+ }
+
+ return _dropAreas;
+ }
+
+ #region HideWindowCommand
+ public ICommand HideWindowCommand
+ {
+ get;
+ private set;
+ }
+
+ private bool CanExecuteHideWindowCommand(object parameter)
+ {
+ if (Model == null)
+ return false;
+
+ var root = Model.Root;
+ if (root == null)
+ return false;
+
+ var manager = root.Manager;
+ if (manager == null)
+ return false;
+
+ // TODO check CanHide of anchorables
+ bool canExecute = false;
+ foreach (var content in this.Model.Descendents().OfType().ToArray())
+ {
+ if ((content is LayoutAnchorable anchorable && !anchorable.CanHide) ||
+ !content.CanClose)
+ {
+ canExecute = false;
+ break;
+ }
+
+ //if (!(manager.GetLayoutItemFromModel(content) is LayoutAnchorableItem layoutAnchorableItem) ||
+ // layoutAnchorableItem.HideCommand == null ||
+ // !layoutAnchorableItem.HideCommand.CanExecute(parameter))
+ //{
+ // canExecute = false;
+ // break;
+ //}
+ if (!(manager.GetLayoutItemFromModel(content) is LayoutItem layoutItem) ||
+ layoutItem.CloseCommand == null ||
+ !layoutItem.CloseCommand.CanExecute(parameter))
+ {
+ canExecute = false;
+ break;
+ }
+
+ canExecute = true;
+ }
+
+ return canExecute;
+ }
+
+ private void OnExecuteHideWindowCommand(object parameter)
+ {
+ var manager = Model.Root.Manager;
+ foreach (var anchorable in this.Model.Descendents().OfType().ToArray())
+ {
+ //if (manager.GetLayoutItemFromModel(anchorable) is LayoutAnchorableItem layoutAnchorableItem) layoutAnchorableItem.HideCommand.Execute(parameter);
+ //else
+ if (manager.GetLayoutItemFromModel(anchorable) is LayoutItem layoutItem) layoutItem.CloseCommand.Execute(parameter);
+ }
+ }
+ #endregion
+
+
#endregion
}
}
diff --git a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
index 0f99da0b..b40213c4 100644
--- a/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
+++ b/source/Components/Xceed.Wpf.AvalonDock/Controls/LayoutDocumentPaneControl.cs
@@ -27,7 +27,6 @@ public class LayoutDocumentPaneControl : TabControl, ILayoutControl//, ILogicalC
{
#region Members
- private List
-
@@ -1087,14 +1085,12 @@
Value="3"
TargetName="WindowBorder" />
-
From 49274532eb8d642b0877e96cff43fbb399d5dc8a Mon Sep 17 00:00:00 2001
From: Marco Konijnenburg
Date: Fri, 24 Jan 2020 14:16:01 +0100
Subject: [PATCH 5/5] Fixed drag last document floating window placement. Added
check for Model.Root not null, or should it always be set somewhere.
---
.../Controls/AnchorablePaneDropTarget.cs | 5 -
.../Controls/DocumentPaneDropTarget.cs | 271 ++++++++--------
.../Controls/DocumentPaneGroupDropTarget.cs | 4 +-
.../AvalonDock/Controls/DragService.cs | 1 +
.../LayoutDocumentFloatingWindowControl.cs | 298 ++++++++++++++++--
.../Controls/LayoutDocumentPaneControl.cs | 17 -
.../Controls/LayoutFloatingWindowControl.cs | 2 -
.../Components/AvalonDock/DockingManager.cs | 43 ++-
.../Layout/LayoutDocumentFloatingWindow.cs | 127 ++++++--
.../AvalonDock/Layout/LayoutDocumentPane.cs | 123 +++++---
.../AvalonDock/Layout/LayoutRoot.cs | 15 +
11 files changed, 639 insertions(+), 267 deletions(-)
diff --git a/source/Components/AvalonDock/Controls/AnchorablePaneDropTarget.cs b/source/Components/AvalonDock/Controls/AnchorablePaneDropTarget.cs
index 00f8372c..3e531140 100644
--- a/source/Components/AvalonDock/Controls/AnchorablePaneDropTarget.cs
+++ b/source/Components/AvalonDock/Controls/AnchorablePaneDropTarget.cs
@@ -253,11 +253,6 @@ protected override void Drop(LayoutAnchorableFloatingWindow floatingWindow)
public override System.Windows.Media.Geometry GetPreviewPath(OverlayWindow overlayWindow, LayoutFloatingWindow floatingWindowModel)
{
- //var anchorablePaneDropTarget = target as AnchorablePaneDropTarget;
- var anchorableFloatingWindowModel = floatingWindowModel as LayoutAnchorableFloatingWindow;
- var layoutAnchorablePane = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElement;
- var layoutAnchorablePaneWithActualSize = anchorableFloatingWindowModel.RootPanel as ILayoutPositionableElementWithActualSize;
-
switch (Type)
{
case DropTargetType.AnchorablePaneDockBottom:
diff --git a/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs b/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs
index 4df1b3df..c5dafede 100644
--- a/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs
+++ b/source/Components/AvalonDock/Controls/DocumentPaneDropTarget.cs
@@ -45,185 +45,206 @@ internal DocumentPaneDropTarget(LayoutDocumentPaneControl paneControl, Rect dete
protected override void Drop(LayoutDocumentFloatingWindow floatingWindow)
{
ILayoutDocumentPane targetModel = _targetPane.Model as ILayoutDocumentPane;
+ LayoutDocument documentActive = floatingWindow.Descendents().OfType().FirstOrDefault();
switch (Type)
{
case DropTargetType.DocumentPaneDockBottom:
#region DropTargetType.DocumentPaneDockBottom
- {
- var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument);
- var parentModel = targetModel.Parent as LayoutDocumentPaneGroup;
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
- if (parentModel == null)
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
{
- var parentContainer = targetModel.Parent as ILayoutContainer;
- var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical };
- parentContainer.ReplaceChild(targetModel, newParentModel);
- newParentModel.Children.Add(targetModel as LayoutDocumentPane);
- newParentModel.Children.Add(newLayoutDocumentPane);
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + 1 + i, documentsToMove[i]);
}
else
+ parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
{
- var manager = parentModel.Root.Manager;
- if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical)
- {
- parentModel.Orientation = System.Windows.Controls.Orientation.Vertical;
- int targetPaneIndex = parentModel.IndexOfChild(targetModel);
- parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane);
- }
- else
- {
- LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup();
- newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical;
- parentModel.ReplaceChild(targetModel, newChildGroup);
- newChildGroup.Children.Add(targetModel);
- newChildGroup.Children.Add(newLayoutDocumentPane);
- }
+ Orientation = System.Windows.Controls.Orientation.Vertical,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Add(floatingWindow.RootPanel);
- }
}
+ }
break;
+
#endregion
case DropTargetType.DocumentPaneDockTop:
#region DropTargetType.DocumentPaneDockTop
- {
- var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument);
- var parentModel = targetModel.Parent as LayoutDocumentPaneGroup;
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
- if (parentModel == null)
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Vertical &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Vertical;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Vertical)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Vertical))
{
- var parentContainer = targetModel.Parent as ILayoutContainer;
- var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical };
- parentContainer.ReplaceChild(targetModel, newParentModel);
- newParentModel.Children.Add(targetModel as LayoutDocumentPane);
- newParentModel.Children.Insert(0, newLayoutDocumentPane);
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + i, documentsToMove[i]);
}
else
+ parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
{
- var manager = parentModel.Root.Manager;
- if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Vertical)
- {
- parentModel.Orientation = System.Windows.Controls.Orientation.Vertical;
- int targetPaneIndex = parentModel.IndexOfChild(targetModel);
- parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane);
- }
- else
- {
- LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup();
- newChildGroup.Orientation = System.Windows.Controls.Orientation.Vertical;
- parentModel.ReplaceChild(targetModel, newChildGroup);
- newChildGroup.Children.Add(newLayoutDocumentPane);
- newChildGroup.Children.Add(targetModel);
- }
+ Orientation = System.Windows.Controls.Orientation.Vertical,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ //the floating window must be added after the target modal as it could be raise a CollectGarbage call
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
- }
}
+ }
break;
#endregion
case DropTargetType.DocumentPaneDockLeft:
#region DropTargetType.DocumentPaneDockLeft
- {
- var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument);
- var parentModel = targetModel.Parent as LayoutDocumentPaneGroup;
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
- if (parentModel == null)
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
{
- var parentContainer = targetModel.Parent as ILayoutContainer;
- var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal };
- parentContainer.ReplaceChild(targetModel, newParentModel);
- newParentModel.Children.Add(targetModel);
- newParentModel.Children.Insert(0, newLayoutDocumentPane);
+ var documentsToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentsToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + i, documentsToMove[i]);
}
else
+ parentModel.InsertChildAt(insertToIndex, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
{
- var manager = parentModel.Root.Manager;
- if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal)
- {
- parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal;
- int targetPaneIndex = parentModel.IndexOfChild(targetModel);
- parentModel.Children.Insert(targetPaneIndex, newLayoutDocumentPane);
- }
- else
- {
- LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup();
- newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal;
- parentModel.ReplaceChild(targetModel, newChildGroup);
- newChildGroup.Children.Add(newLayoutDocumentPane);
- newChildGroup.Children.Add(targetModel);
- }
- }
+ Orientation = System.Windows.Controls.Orientation.Horizontal,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ //the floating window must be added after the target modal as it could be raise a CollectGarbage call
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Insert(0, floatingWindow.RootPanel);
+
}
+ }
break;
#endregion
case DropTargetType.DocumentPaneDockRight:
#region DropTargetType.DocumentPaneDockRight
- {
- var newLayoutDocumentPane = new LayoutDocumentPane(floatingWindow.RootDocument);
- var parentModel = targetModel.Parent as LayoutDocumentPaneGroup;
+ {
+ var parentModel = targetModel.Parent as ILayoutGroup;
+ var parentModelOrientable = targetModel.Parent as ILayoutOrientableGroup;
+ int insertToIndex = parentModel.IndexOfChild(targetModel);
- if (parentModel == null)
+ if (parentModelOrientable.Orientation != System.Windows.Controls.Orientation.Horizontal &&
+ parentModel.ChildrenCount == 1)
+ parentModelOrientable.Orientation = System.Windows.Controls.Orientation.Horizontal;
+
+ if (parentModelOrientable.Orientation == System.Windows.Controls.Orientation.Horizontal)
+ {
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
+ if (layoutDocumentPaneGroup != null &&
+ (layoutDocumentPaneGroup.Children.Count == 1 ||
+ layoutDocumentPaneGroup.Orientation == System.Windows.Controls.Orientation.Horizontal))
{
- var parentContainer = targetModel.Parent as ILayoutContainer;
- var newParentModel = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Horizontal };
- parentContainer.ReplaceChild(targetModel, newParentModel);
- newParentModel.Children.Add(targetModel as LayoutDocumentPane);
- newParentModel.Children.Add(newLayoutDocumentPane);
+ var documentToMove = layoutDocumentPaneGroup.Children.ToArray();
+ for (int i = 0; i < documentToMove.Length; i++)
+ parentModel.InsertChildAt(insertToIndex + 1 + i, documentToMove[i]);
}
else
+ parentModel.InsertChildAt(insertToIndex + 1, floatingWindow.RootPanel);
+ }
+ else
+ {
+ var targetModelAsPositionableElement = targetModel as ILayoutPositionableElement;
+ var newOrientedPanel = new LayoutDocumentPaneGroup()
{
- var manager = parentModel.Root.Manager;
- if (!manager.AllowMixedOrientation || parentModel.Orientation == System.Windows.Controls.Orientation.Horizontal)
- {
- parentModel.Orientation = System.Windows.Controls.Orientation.Horizontal;
- int targetPaneIndex = parentModel.IndexOfChild(targetModel);
- parentModel.Children.Insert(targetPaneIndex + 1, newLayoutDocumentPane);
- }
- else
- {
- LayoutDocumentPaneGroup newChildGroup = new LayoutDocumentPaneGroup();
- newChildGroup.Orientation = System.Windows.Controls.Orientation.Horizontal;
- parentModel.ReplaceChild(targetModel, newChildGroup);
- newChildGroup.Children.Add(targetModel);
- newChildGroup.Children.Add(newLayoutDocumentPane);
- }
+ Orientation = System.Windows.Controls.Orientation.Horizontal,
+ DockWidth = targetModelAsPositionableElement.DockWidth,
+ DockHeight = targetModelAsPositionableElement.DockHeight,
+ };
+
+ parentModel.InsertChildAt(insertToIndex, newOrientedPanel);
+ newOrientedPanel.Children.Add(targetModel);
+ newOrientedPanel.Children.Add(floatingWindow.RootPanel);
- }
}
+ }
break;
#endregion
case DropTargetType.DocumentPaneDockInside:
#region DropTargetType.DocumentPaneDockInside
- {
- var paneModel = targetModel as LayoutDocumentPane;
- var sourceModel = floatingWindow.RootDocument;
+ {
+ var paneModel = targetModel as LayoutDocumentPane;
+ var layoutDocumentPaneGroup = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
- int i = 0;
- if (_tabIndex != -1)
- {
- i = _tabIndex;
- }
- else
- {
- var previousIndex = 0;
- var previousContainer = ((ILayoutPreviousContainer)sourceModel).PreviousContainer;
- if (object.ReferenceEquals(previousContainer, targetModel) && (sourceModel.PreviousContainerIndex != -1))
- {
- previousIndex = sourceModel.PreviousContainerIndex;
- }
-
- i = previousIndex;
- }
- sourceModel.IsActive = false;
- paneModel.Children.Insert(System.Math.Min(paneModel.Children.Count, i), sourceModel);
- sourceModel.IsActive = true;
+ int i = _tabIndex == -1 ? 0 : _tabIndex;
+ foreach (var anchorableToImport in
+ layoutDocumentPaneGroup.Descendents().OfType().ToArray())
+ {
+ paneModel.Children.Insert(i, anchorableToImport);
+ i++;
}
+ }
break;
- #endregion
-
-
+ #endregion
}
+ documentActive.IsActive = true;
+
base.Drop(floatingWindow);
}
diff --git a/source/Components/AvalonDock/Controls/DocumentPaneGroupDropTarget.cs b/source/Components/AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
index 5e249d76..7a41da17 100644
--- a/source/Components/AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
+++ b/source/Components/AvalonDock/Controls/DocumentPaneGroupDropTarget.cs
@@ -44,8 +44,8 @@ protected override void Drop(LayoutDocumentFloatingWindow floatingWindow)
#region DropTargetType.DocumentPaneGroupDockInside
{
var paneGroupModel = targetModel as LayoutDocumentPaneGroup;
- var paneModel = paneGroupModel.Children[0] as LayoutDocumentPane;
- var sourceModel = floatingWindow.RootDocument;
+ var paneModel = paneGroupModel as LayoutDocumentPaneGroup;
+ var sourceModel = floatingWindow.RootPanel as LayoutDocumentPaneGroup;
paneModel.Children.Insert(0, sourceModel);
}
diff --git a/source/Components/AvalonDock/Controls/DragService.cs b/source/Components/AvalonDock/Controls/DragService.cs
index cfc0f1f9..4ed0c635 100644
--- a/source/Components/AvalonDock/Controls/DragService.cs
+++ b/source/Components/AvalonDock/Controls/DragService.cs
@@ -186,6 +186,7 @@ internal void Abort()
private void GetOverlayWindowHosts()
{
_overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType().Where(fw => fw != _floatingWindow && fw.IsVisible));
+ _overlayWindowHosts.AddRange(_manager.GetFloatingWindowsByZOrder().OfType().Where(fw => fw != _floatingWindow && fw.IsVisible));
_overlayWindowHosts.Add(_manager);
}
diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
index f2c981c8..bbd210af 100644
--- a/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
+++ b/source/Components/AvalonDock/Controls/LayoutDocumentFloatingWindowControl.cs
@@ -8,14 +8,18 @@ This program is provided to you under the terms of the Microsoft Public
************************************************************************/
using System;
+using System.Collections.Generic;
+using System.Linq;
using AvalonDock.Layout;
using System.Windows;
using System.Windows.Controls.Primitives;
+using System.Windows.Input;
+using AvalonDock.Commands;
using Microsoft.Windows.Shell;
namespace AvalonDock.Controls
{
- public class LayoutDocumentFloatingWindowControl : LayoutFloatingWindowControl
+ public class LayoutDocumentFloatingWindowControl : LayoutFloatingWindowControl, IOverlayWindowHost
{
#region Members
@@ -34,6 +38,9 @@ internal LayoutDocumentFloatingWindowControl(LayoutDocumentFloatingWindow model,
: base(model, isContentImmutable)
{
_model = model;
+ HideWindowCommand = new RelayCommand((p) => OnExecuteHideWindowCommand(p), (p) => CanExecuteHideWindowCommand(p));
+ CloseWindowCommand = new RelayCommand((p) => OnExecuteCloseWindowCommand(p), (p) => CanExecuteCloseWindowCommand(p));
+ Closed += (sender, args) => { Owner?.Focus(); };
UpdateThemeResources();
}
@@ -44,43 +51,72 @@ internal LayoutDocumentFloatingWindowControl(LayoutDocumentFloatingWindow model)
#endregion
- #region Properties
+ #region Overrides
- public LayoutItem RootDocumentLayoutItem
+ public override ILayoutElement Model
{
get
{
- return _model.Root.Manager.GetLayoutItemFromModel(_model.RootDocument);
+ return _model;
}
}
- #endregion
+ #region SingleContentLayoutItem
+
+ ///
+ /// SingleContentLayoutItem Dependency Property
+ ///
+ public static readonly DependencyProperty SingleContentLayoutItemProperty =
+ DependencyProperty.Register("SingleContentLayoutItem", typeof(LayoutItem), typeof(LayoutDocumentFloatingWindowControl),
+ new FrameworkPropertyMetadata((LayoutItem)null,
+ new PropertyChangedCallback(OnSingleContentLayoutItemChanged)));
+
+ ///
+ /// Gets or sets the SingleContentLayoutItem property. This dependency property
+ /// indicates the layout item of the selected content when is shown a single document pane.
+ ///
+ public LayoutItem SingleContentLayoutItem
+ {
+ get { return (LayoutItem)GetValue(SingleContentLayoutItemProperty); }
+ set { SetValue(SingleContentLayoutItemProperty, value); }
+ }
- #region Overrides
+ ///
+ /// Handles changes to the property.
+ ///
+ private static void OnSingleContentLayoutItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((LayoutDocumentFloatingWindowControl)d).OnSingleContentLayoutItemChanged(e);
+ }
- public override ILayoutElement Model
+ ///
+ /// Provides derived classes an opportunity to handle changes to the property.
+ ///
+ protected virtual void OnSingleContentLayoutItemChanged(DependencyPropertyChangedEventArgs e)
{
- get
- {
- return _model;
- }
}
+ #endregion
+
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
- if (_model.RootDocument == null)
- {
- InternalClose();
- }
- else
- {
- var manager = _model.Root.Manager;
+ var manager = _model.Root.Manager;
- Content = manager.CreateUIElementForModel(_model.RootDocument);
+ Content = manager.CreateUIElementForModel(_model.RootPanel);
+ // TODO IsVisibleChanged
+ //SetBinding(SingleContentLayoutItemProperty, new Binding("Model.SinglePane.SelectedContent") { Source = this, Converter = new LayoutItemFromLayoutModelConverter() });
- _model.RootDocumentChanged += new EventHandler(_model_RootDocumentChanged);
+ _model.RootPanel.ChildrenCollectionChanged += RootPanelOnChildrenCollectionChanged;
+ }
+
+ void _model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "RootPanel" &&
+ _model.RootPanel == null)
+ {
+ InternalClose();
}
}
@@ -91,8 +127,8 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int
case Win32Helper.WM_NCLBUTTONDOWN: //Left button down on title -> start dragging over docking manager
if (wParam.ToInt32() == Win32Helper.HT_CAPTION)
{
- if (_model.RootDocument != null)
- _model.RootDocument.IsActive = true;
+ _model.Descendents().OfType().First(p => p.ChildrenCount > 0 && p.SelectedContent != null).SelectedContent.IsActive = true;
+ handled = true;
}
break;
case Win32Helper.WM_NCRBUTTONUP:
@@ -115,26 +151,36 @@ protected override IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, Int
protected override void OnClosed(EventArgs e)
{
var root = Model.Root;
- root.Manager.RemoveFloatingWindow(this);
- root.CollectGarbage();
+ // MK sometimes root is null, prevent crash, or should it always be set??
+ if (root != null)
+ {
+ root.Manager.RemoveFloatingWindow(this);
+ root.CollectGarbage();
+ }
+
+ if (_overlayWindow != null)
+ {
+ _overlayWindow.Close();
+ _overlayWindow = null;
+ }
base.OnClosed(e);
if (!CloseInitiatedByUser)
{
- root.FloatingWindows.Remove(_model);
+ root?.FloatingWindows.Remove(_model);
}
- _model.RootDocumentChanged -= new EventHandler(_model_RootDocumentChanged);
+ _model.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(_model_PropertyChanged);
}
#endregion
#region Private Methods
- private void _model_RootDocumentChanged(object sender, EventArgs e)
+ private void RootPanelOnChildrenCollectionChanged(object sender, EventArgs e)
{
- if (_model.RootDocument == null)
+ if( _model.RootPanel == null ||_model.RootPanel.Children.Count == 0)
{
InternalClose();
}
@@ -143,11 +189,11 @@ private void _model_RootDocumentChanged(object sender, EventArgs e)
private bool OpenContextMenu()
{
var ctxMenu = _model.Root.Manager.DocumentContextMenu;
- if (ctxMenu != null && RootDocumentLayoutItem != null)
+ if (ctxMenu != null && SingleContentLayoutItem != null)
{
ctxMenu.PlacementTarget = null;
ctxMenu.Placement = PlacementMode.MousePoint;
- ctxMenu.DataContext = RootDocumentLayoutItem;
+ ctxMenu.DataContext = SingleContentLayoutItem;
ctxMenu.IsOpen = true;
return true;
}
@@ -155,6 +201,196 @@ private bool OpenContextMenu()
return false;
}
+ protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
+ {
+ // TODO
+ if (CloseInitiatedByUser && !KeepContentVisibleOnClose)
+ {
+ e.Cancel = true;
+ //_model.Descendents().OfType().ToArray().ForEach((a) => a.Hide());
+ }
+
+ base.OnClosing(e);
+ }
+
+ bool IOverlayWindowHost.HitTest(Point dragPoint)
+ {
+ Rect detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor());
+ return detectionRect.Contains(dragPoint);
+ }
+
+ DockingManager IOverlayWindowHost.Manager
+ {
+ get { return _model.Root.Manager; }
+ }
+
+ OverlayWindow _overlayWindow = null;
+
+ void CreateOverlayWindow()
+ {
+ if (_overlayWindow == null)
+ _overlayWindow = new OverlayWindow(this);
+ Rect rectWindow = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor());
+ _overlayWindow.Left = rectWindow.Left;
+ _overlayWindow.Top = rectWindow.Top;
+ _overlayWindow.Width = rectWindow.Width;
+ _overlayWindow.Height = rectWindow.Height;
+ }
+
+ IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow)
+ {
+ CreateOverlayWindow();
+ _overlayWindow.Owner = draggingWindow;
+ _overlayWindow.EnableDropTargets();
+ _overlayWindow.Show();
+
+ return _overlayWindow;
+ }
+
+ public void HideOverlayWindow()
+ {
+ _dropAreas = null;
+ _overlayWindow.Owner = null;
+ _overlayWindow.HideDropTargets();
+ }
+
+ List _dropAreas = null;
+ public IEnumerable GetDropAreas(LayoutFloatingWindowControl draggingWindow)
+ {
+ if (_dropAreas != null)
+ return _dropAreas;
+
+ _dropAreas = new List();
+
+ var rootVisual = (Content as FloatingWindowContentHost).RootVisual;
+
+ foreach (var areaHost in rootVisual.FindVisualChildren())
+ {
+ _dropAreas.Add(new DropArea(
+ areaHost,
+ DropAreaType.AnchorablePane));
+ }
+ foreach (var areaHost in rootVisual.FindVisualChildren())
+ {
+ _dropAreas.Add(new DropArea(
+ areaHost,
+ DropAreaType.DocumentPane));
+ }
+
+ return _dropAreas;
+ }
+
+ #region HideWindowCommand
+ public ICommand HideWindowCommand
+ {
+ get;
+ private set;
+ }
+
+ private bool CanExecuteHideWindowCommand(object parameter)
+ {
+ if (Model == null)
+ return false;
+
+ var root = Model.Root;
+ if (root == null)
+ return false;
+
+ var manager = root.Manager;
+ if (manager == null)
+ return false;
+
+ // TODO check CanHide of anchorables
+ bool canExecute = false;
+ foreach (var content in this.Model.Descendents().OfType().ToArray())
+ {
+ if ((content is LayoutAnchorable anchorable && !anchorable.CanHide) ||
+ !content.CanClose)
+ {
+ canExecute = false;
+ break;
+ }
+
+ //if (!(manager.GetLayoutItemFromModel(content) is LayoutAnchorableItem layoutAnchorableItem) ||
+ // layoutAnchorableItem.HideCommand == null ||
+ // !layoutAnchorableItem.HideCommand.CanExecute(parameter))
+ //{
+ // canExecute = false;
+ // break;
+ //}
+ if (!(manager.GetLayoutItemFromModel(content) is LayoutItem layoutItem) ||
+ layoutItem.CloseCommand == null ||
+ !layoutItem.CloseCommand.CanExecute(parameter))
+ {
+ canExecute = false;
+ break;
+ }
+
+ canExecute = true;
+ }
+
+ return canExecute;
+ }
+
+ private void OnExecuteHideWindowCommand(object parameter)
+ {
+ var manager = Model.Root.Manager;
+ foreach (var anchorable in this.Model.Descendents().OfType().ToArray())
+ {
+ //if (manager.GetLayoutItemFromModel(anchorable) is LayoutAnchorableItem layoutAnchorableItem) layoutAnchorableItem.HideCommand.Execute(parameter);
+ //else
+ if (manager.GetLayoutItemFromModel(anchorable) is LayoutItem layoutItem) layoutItem.CloseCommand.Execute(parameter);
+ }
+ }
+ #endregion
+
+ #region CloseWindowCommand
+ public ICommand CloseWindowCommand
+ {
+ get;
+ private set;
+ }
+
+ private bool CanExecuteCloseWindowCommand( object parameter )
+ {
+ var manager = Model?.Root?.Manager;
+ if( manager == null )
+ return false;
+
+ var canExecute = false;
+ foreach( var document in this.Model.Descendents().OfType().ToArray() )
+ {
+ if( !document.CanClose )
+ {
+ canExecute = false;
+ break;
+ }
+
+ if( !(manager.GetLayoutItemFromModel( document ) is LayoutDocumentItem documentLayoutItem) ||
+ documentLayoutItem.CloseCommand == null ||
+ !documentLayoutItem.CloseCommand.CanExecute( parameter ) )
+ {
+ canExecute = false;
+ break;
+ }
+ canExecute = true;
+ }
+
+ return canExecute;
+ }
+
+ private void OnExecuteCloseWindowCommand( object parameter )
+ {
+ var manager = Model.Root.Manager;
+ foreach( var document in this.Model.Descendents().OfType().ToArray() )
+ {
+ var documentLayoutItem = manager.GetLayoutItemFromModel( document ) as LayoutDocumentItem;
+ documentLayoutItem?.CloseCommand.Execute(parameter);
+ }
+ }
+
#endregion
- }
+
+ #endregion
+ }
}
diff --git a/source/Components/AvalonDock/Controls/LayoutDocumentPaneControl.cs b/source/Components/AvalonDock/Controls/LayoutDocumentPaneControl.cs
index 293d51aa..4e7563b4 100644
--- a/source/Components/AvalonDock/Controls/LayoutDocumentPaneControl.cs
+++ b/source/Components/AvalonDock/Controls/LayoutDocumentPaneControl.cs
@@ -20,7 +20,6 @@ public class LayoutDocumentPaneControl : TabControl, ILayoutControl//, ILogicalC
{
#region Members
- private List _logicalChildren = new List();
private LayoutDocumentPane _model;
#endregion
@@ -62,22 +61,6 @@ public ILayoutElement Model
#region Overrides
- protected override System.Collections.IEnumerator LogicalChildren
- {
- get
- {
- return _logicalChildren.GetEnumerator();
- }
- }
-
- protected override void OnSelectionChanged(SelectionChangedEventArgs e)
- {
- base.OnSelectionChanged(e);
-
- if (_model.SelectedContent != null)
- _model.SelectedContent.IsActive = true;
- }
-
protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
diff --git a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
index 5a5ea4dd..34c17b60 100644
--- a/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
+++ b/source/Components/AvalonDock/Controls/LayoutFloatingWindowControl.cs
@@ -483,8 +483,6 @@ private void OnActivated(object sender, EventArgs e)
{
IntPtr windowHandle = new WindowInteropHelper(this).Handle;
var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this));
- var clientArea = Win32Helper.GetClientRect(windowHandle);
- var windowArea = Win32Helper.GetWindowRect(windowHandle);
// BugFix Issue #6
// This code is initializes the drag when content (document or toolwindow) is dragged
diff --git a/source/Components/AvalonDock/DockingManager.cs b/source/Components/AvalonDock/DockingManager.cs
index cf6155e8..18ba44d2 100644
--- a/source/Components/AvalonDock/DockingManager.cs
+++ b/source/Components/AvalonDock/DockingManager.cs
@@ -2132,7 +2132,7 @@ internal UIElement CreateUIElementForModel(ILayoutElement model)
};
newFW.SetParentToMainWindowOf(this);
- var paneForExtensions = modelFW.RootDocument;
+ var paneForExtensions = modelFW.RootPanel;
if (paneForExtensions != null)
{
//ensure that floating window position is inside current (or nearest) monitor
@@ -2201,15 +2201,31 @@ internal void StartDraggingFloatingWindowForContent(LayoutContent contentModel,
if (contentModel.CanFloat == false)
return;
- var fwc = this.CreateFloatingWindow(contentModel, false);
+ LayoutFloatingWindowControl fwc = null;
+
+ // For last document re-use floating window
+ if (contentModel.Parent.ChildrenCount == 1)
+ {
+ foreach (var fw in _fwList)
+ foreach (var layoutElement in ((LayoutDocumentFloatingWindow)fw.Model).Children)
+ foreach (var pane in ((LayoutDocumentPaneGroup)layoutElement).Children)
+ foreach (var layoutDoc in ((LayoutDocumentPane)pane).Children)
+ if (layoutDoc == contentModel)
+ fwc = fw;
+ }
+
+ var show = fwc == null; // Do not show already visible floating window
+ if (fwc == null)
+ fwc = this.CreateFloatingWindow(contentModel, false);
+
if (fwc != null)
{
Dispatcher.BeginInvoke(new Action(() =>
- {
- if (startDrag)
- fwc.AttachDrag();
- fwc.Show();
- }), DispatcherPriority.Send);
+ {
+ // Activate only inactive document
+ if (startDrag) fwc.AttachDrag();
+ if (show) fwc.Show();
+ }), DispatcherPriority.Send);
}
}
@@ -3330,7 +3346,18 @@ private LayoutFloatingWindowControl CreateFloatingWindowCore(LayoutContent conte
var anchorableDocument = contentModel as LayoutDocument;
fw = new LayoutDocumentFloatingWindow()
{
- RootDocument = anchorableDocument
+ RootPanel = new LayoutDocumentPaneGroup(
+ new LayoutDocumentPane(anchorableDocument)
+ {
+ DockWidth = parentPaneAsPositionableElement.DockWidth,
+ DockHeight = parentPaneAsPositionableElement.DockHeight,
+ DockMinHeight = parentPaneAsPositionableElement.DockMinHeight,
+ DockMinWidth = parentPaneAsPositionableElement.DockMinWidth,
+ FloatingLeft = parentPaneAsPositionableElement.FloatingLeft,
+ FloatingTop = parentPaneAsPositionableElement.FloatingTop,
+ FloatingWidth = parentPaneAsPositionableElement.FloatingWidth,
+ FloatingHeight = parentPaneAsPositionableElement.FloatingHeight,
+ })
};
Layout.FloatingWindows.Add(fw);
diff --git a/source/Components/AvalonDock/Layout/LayoutDocumentFloatingWindow.cs b/source/Components/AvalonDock/Layout/LayoutDocumentFloatingWindow.cs
index a85ac2d6..a67e1ec8 100644
--- a/source/Components/AvalonDock/Layout/LayoutDocumentFloatingWindow.cs
+++ b/source/Components/AvalonDock/Layout/LayoutDocumentFloatingWindow.cs
@@ -11,14 +11,15 @@ This program is provided to you under the terms of the Microsoft Public
using System.Collections.Generic;
using System.Windows.Markup;
using System.Diagnostics;
+using System.Linq;
using System.Xml.Serialization;
using System.Xml;
namespace AvalonDock.Layout
{
- [ContentProperty("RootDocument")]
+ [ContentProperty("RootPanel")]
[Serializable]
- public class LayoutDocumentFloatingWindow : LayoutFloatingWindow
+ public class LayoutDocumentFloatingWindow : LayoutFloatingWindow, ILayoutElementWithVisibility
{
#region Constructors
@@ -30,31 +31,68 @@ public LayoutDocumentFloatingWindow()
#region Properties
- #region RootDocument
+ #region RootPanel
- private LayoutDocument _rootDocument = null;
- public LayoutDocument RootDocument
+ private LayoutDocumentPaneGroup _rootPanel = null;
+ public LayoutDocumentPaneGroup RootPanel
{
get
{
- return _rootDocument;
+ return _rootPanel;
}
set
{
- if (_rootDocument != value)
+ if( _rootPanel != value )
{
- RaisePropertyChanging("RootDocument");
- _rootDocument = value;
- if (_rootDocument != null)
- _rootDocument.Parent = this;
- RaisePropertyChanged("RootDocument");
-
- if (RootDocumentChanged != null)
- RootDocumentChanged(this, EventArgs.Empty);
+ if (_rootPanel != null)
+ _rootPanel.ChildrenTreeChanged -= new EventHandler(_rootPanel_ChildrenTreeChanged);
+
+ _rootPanel = value;
+ if (_rootPanel != null)
+ _rootPanel.Parent = this;
+
+ if (_rootPanel != null)
+ _rootPanel.ChildrenTreeChanged += new EventHandler(_rootPanel_ChildrenTreeChanged);
+
+ RaisePropertyChanged("RootPanel");
+ RaisePropertyChanged("IsSinglePane");
+ RaisePropertyChanged("SinglePane");
+ RaisePropertyChanged("Children");
+ RaisePropertyChanged("ChildrenCount");
+ ((ILayoutElementWithVisibility)this).ComputeVisibility();
}
}
}
+ void _rootPanel_ChildrenTreeChanged(object sender, ChildrenTreeChangedEventArgs e)
+ {
+ RaisePropertyChanged("IsSinglePane");
+ RaisePropertyChanged("SinglePane");
+
+ }
+
+ public bool IsSinglePane
+ {
+ get
+ {
+ return RootPanel != null && RootPanel.Descendents().OfType().Where(p => p.IsVisible).Count() == 1;
+ }
+ }
+
+ public ILayoutDocumentPane SinglePane
+ {
+ get
+ {
+ if (!IsSinglePane)
+ return null;
+
+ var singlePane = RootPanel.Descendents().OfType().Single(p => p.IsVisible);
+ //singlePane.UpdateIsDirectlyHostedInFloatingWindow();
+ return singlePane;
+ }
+ }
+
+
#endregion
#endregion
@@ -65,38 +103,67 @@ public override IEnumerable Children
{
get
{
- if (RootDocument == null)
- yield break;
-
- yield return RootDocument;
+ if (ChildrenCount == 1)
+ yield return RootPanel;
}
}
public override void RemoveChild(ILayoutElement element)
{
- Debug.Assert(element == RootDocument && element != null);
- RootDocument = null;
+ Debug.Assert( element == RootPanel && element != null );
+ RootPanel = null;
}
public override void ReplaceChild(ILayoutElement oldElement, ILayoutElement newElement)
{
- Debug.Assert(oldElement == RootDocument && oldElement != null);
- RootDocument = newElement as LayoutDocument;
+ Debug.Assert( oldElement == RootPanel && oldElement != null );
+ RootPanel = newElement as LayoutDocumentPaneGroup;
}
public override int ChildrenCount
{
get
{
- return RootDocument != null ? 1 : 0;
+ return RootPanel == null ? 0 : 1;
}
}
+ #region IsVisible
+ [NonSerialized]
+ private bool _isVisible = true;
+
+ [XmlIgnore]
+ public bool IsVisible
+ {
+ get { return _isVisible; }
+ private set
+ {
+ if (_isVisible != value)
+ {
+ RaisePropertyChanging("IsVisible");
+ _isVisible = value;
+ RaisePropertyChanged("IsVisible");
+ if (IsVisibleChanged != null)
+ IsVisibleChanged(this, EventArgs.Empty);
+ }
+ }
+ }
+
+ public event EventHandler IsVisibleChanged;
+
+ #endregion
+
+ void ILayoutElementWithVisibility.ComputeVisibility()
+ {
+ IsVisible = RootPanel != null && RootPanel.IsVisible;
+ }
+
+
public override bool IsValid
{
get
{
- return RootDocument != null;
+ return RootPanel != null;
}
}
@@ -140,7 +207,7 @@ public override void ReadXml(XmlReader reader)
serializer = new XmlSerializer(type);
}
- RootDocument = (LayoutDocument)serializer.Deserialize(reader);
+ RootPanel = (LayoutDocumentPaneGroup)serializer.Deserialize(reader);
}
reader.ReadEndElement();
@@ -152,16 +219,10 @@ public override void ConsoleDump(int tab)
System.Diagnostics.Trace.Write(new string(' ', tab * 4));
System.Diagnostics.Trace.WriteLine("FloatingDocumentWindow()");
- RootDocument.ConsoleDump(tab + 1);
+ RootPanel.ConsoleDump(tab + 1);
}
#endif
#endregion
-
- #region Events
-
- public event EventHandler RootDocumentChanged;
-
- #endregion
}
}
diff --git a/source/Components/AvalonDock/Layout/LayoutDocumentPane.cs b/source/Components/AvalonDock/Layout/LayoutDocumentPane.cs
index 838597cd..1436101b 100644
--- a/source/Components/AvalonDock/Layout/LayoutDocumentPane.cs
+++ b/source/Components/AvalonDock/Layout/LayoutDocumentPane.cs
@@ -11,6 +11,7 @@ This program is provided to you under the terms of the Microsoft Public
using System.Collections.Generic;
using System.Linq;
using System.Windows.Markup;
+using System.Xml.Serialization;
namespace AvalonDock.Layout
{
@@ -102,20 +103,6 @@ public LayoutContent SelectedContent
#endregion
- #region ChildrenSorted
-
- public IEnumerable ChildrenSorted
- {
- get
- {
- var listSorted = this.Children.ToList();
- listSorted.Sort();
- return listSorted;
- }
- }
-
- #endregion
-
#endregion
#region Overrides
@@ -143,41 +130,49 @@ protected override void ChildMoved(int oldIndex, int newIndex)
protected override void OnChildrenCollectionChanged()
{
- if (this.SelectedContentIndex >= this.ChildrenCount)
- this.SelectedContentIndex = this.Children.Count - 1;
- if (this.SelectedContentIndex == -1)
+ AutoFixSelectedContent();
+ for (int i = 0; i < Children.Count; i++)
{
- if (this.ChildrenCount > 0)
+ if (Children[i].IsSelected)
{
- if (this.Root == null)
- {
- this.SetNextSelectedIndex();
- }
- else
- {
- var childrenToSelect = this.Children.OrderByDescending(c => c.LastActivationTimeStamp.GetValueOrDefault()).First();
- this.SelectedContentIndex = this.Children.IndexOf(childrenToSelect);
- childrenToSelect.IsActive = true;
- }
- }
- else
- {
- if (this.Root != null)
- {
- this.Root.ActiveContent = null;
- }
+ SelectedContentIndex = i;
+ break;
}
}
+ RaisePropertyChanged("CanClose");
+ RaisePropertyChanged("CanHide");
+ RaisePropertyChanged("IsDirectlyHostedInFloatingWindow");
base.OnChildrenCollectionChanged();
- RaisePropertyChanged("ChildrenSorted");
+ RaisePropertyChanged( "ChildrenSorted" );
+ }
+
+ [XmlIgnore]
+ bool _autoFixSelectedContent = true;
+ void AutoFixSelectedContent()
+ {
+ if (_autoFixSelectedContent)
+ {
+ if (SelectedContentIndex >= ChildrenCount)
+ SelectedContentIndex = Children.Count - 1;
+
+ if (SelectedContentIndex == -1 && ChildrenCount > 0)
+ SetNextSelectedIndex();
+ }
}
- protected override void OnIsVisibleChanged()
+ public bool IsDirectlyHostedInFloatingWindow
{
- this.UpdateParentVisibility();
- base.OnIsVisibleChanged();
+ get
+ {
+ var parentFloatingWindow = this.FindParent();
+ if (parentFloatingWindow != null)
+ return parentFloatingWindow.IsSinglePane;
+
+ return false;
+ //return Parent != null && Parent.ChildrenCount == 1 && Parent.Parent is LayoutFloatingWindow;
+ }
}
public override void WriteXml(System.Xml.XmlWriter writer)
@@ -219,7 +214,10 @@ public override void ConsoleDump(int tab)
public int IndexOf(LayoutContent content)
{
- return Children.IndexOf(content);
+ var documentChild = content as LayoutDocument;
+ if (documentChild == null)
+ return -1;
+ return Children.IndexOf(documentChild);
}
#endregion
@@ -243,13 +241,50 @@ internal void SetNextSelectedIndex()
#region Private Methods
- private void UpdateParentVisibility()
+ internal void UpdateIsDirectlyHostedInFloatingWindow()
{
- var parentPane = this.Parent as ILayoutElementWithVisibility;
- if (parentPane != null)
- parentPane.ComputeVisibility();
+ RaisePropertyChanged("IsDirectlyHostedInFloatingWindow");
}
+ public bool IsHostedInFloatingWindow
+ {
+ get
+ {
+ return this.FindParent() != null;
+ }
+ }
+
+ public IEnumerable ChildrenSorted
+ {
+ get
+ {
+ var listSorted = Children.ToList();
+ listSorted.Sort();
+ return listSorted;
+ }
+ }
+
+ protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue)
+ {
+ var oldGroup = oldValue as ILayoutGroup;
+ if (oldGroup != null)
+ oldGroup.ChildrenCollectionChanged -= new EventHandler(OnParentChildrenCollectionChanged);
+
+ RaisePropertyChanged("IsDirectlyHostedInFloatingWindow");
+
+ var newGroup = newValue as ILayoutGroup;
+ if (newGroup != null)
+ newGroup.ChildrenCollectionChanged += new EventHandler(OnParentChildrenCollectionChanged);
+
+ base.OnParentChanged(oldValue, newValue);
+ }
+
+ void OnParentChildrenCollectionChanged(object sender, EventArgs e)
+ {
+ RaisePropertyChanged("IsDirectlyHostedInFloatingWindow");
+ }
+
+
#endregion
#region ILayoutPaneSerializable Interface
diff --git a/source/Components/AvalonDock/Layout/LayoutRoot.cs b/source/Components/AvalonDock/Layout/LayoutRoot.cs
index baceeafa..4d7fdc30 100644
--- a/source/Components/AvalonDock/Layout/LayoutRoot.cs
+++ b/source/Components/AvalonDock/Layout/LayoutRoot.cs
@@ -482,6 +482,21 @@ public void CollectGarbage()
exitFlag = false;
break;
}
+ foreach (var emptyPaneGroup in this.Descendents().OfType().Where(p => p.ChildrenCount == 0))
+ {
+ var parentGroup = emptyPaneGroup.Parent as ILayoutContainer;
+ if (!(parentGroup.Parent is LayoutDocumentFloatingWindow)) continue;
+ var index = RootPanel.IndexOfChild(this.Descendents().OfType().First());
+ parentGroup.RemoveChild(emptyPaneGroup);
+ if (!this.Descendents().OfType().Any())
+ {
+ // Now the last Pane container is deleted, at least one is required for documents to be added.
+ // We did not want to keep an empty window floating, but add a new one to the main window
+ RootPanel.Children.Insert(index < 0 ? 0 : index, emptyPaneGroup);
+ }
+ exitFlag = false;
+ break;
+ }
}
if (!exitFlag)