diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs index b4fc842c..d589bb15 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/AutoHideWindowManager.cs @@ -38,10 +38,13 @@ namespace Xceed.Wpf.AvalonDock.Controls public void ShowAutoHideWindow(LayoutAnchorControl anchor) { + if(_currentAutohiddenAnchor.GetValueOrDefault() != anchor) + { StopCloseTimer(); _currentAutohiddenAnchor = new WeakReference(anchor); _manager.AutoHideWindow.Show(anchor); StartCloseTimer(); + } } public void HideAutoWindow(LayoutAnchorControl anchor = null) @@ -81,6 +84,7 @@ namespace Xceed.Wpf.AvalonDock.Controls { _closeTimer.Stop(); _manager.AutoHideWindow.Hide(); + _currentAutohiddenAnchor = null; } } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs index 206e0927..78b22a19 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/DragService.cs @@ -53,6 +53,8 @@ namespace Xceed.Wpf.AvalonDock.Controls public void UpdateMouseLocation(Point dragPosition) { + if (!_floatingWindow.Model.Root.ActiveContent.CanDock) return; + var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; var newHost = _overlayWindowHosts.FirstOrDefault(oh => oh.HitTest(dragPosition)); @@ -89,8 +91,19 @@ namespace Xceed.Wpf.AvalonDock.Controls } } - if (_currentHost == null) - return; + if (_currentHost == null) + { + Debug.WriteLine("Zero Dock Areas"); + + if(_manager.Parent is DockingManager) + { + _manager = _manager.Parent as DockingManager; + GetOverlayWindowHosts(); + UpdateMouseLocation(dragPosition); + } + + return; + } if (_currentDropTarget != null && !_currentDropTarget.HitTest(dragPosition)) @@ -175,7 +188,8 @@ namespace Xceed.Wpf.AvalonDock.Controls { var floatingWindowModel = _floatingWindow.Model as LayoutFloatingWindow; - _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a)); + if(_currentWindow != null) + _currentWindowAreas.ForEach(a => _currentWindow.DragLeave(a)); if (_currentDropTarget != null) _currentWindow.DragLeave(_currentDropTarget); diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs index 75d33146..f76541b7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/FocusElementManager.cs @@ -87,8 +87,7 @@ namespace Xceed.Wpf.AvalonDock.Controls { var focusedElement = e.NewFocus as Visual; if (focusedElement != null && - !(focusedElement is LayoutAnchorableTabItem || focusedElement is LayoutDocumentTabItem) && - !(focusedElement is ICommandSource))//Avoid tracking focus for elements like this + !(focusedElement is LayoutAnchorableTabItem || focusedElement is LayoutDocumentTabItem)) { var parentAnchorable = focusedElement.FindVisualAncestor(); if (parentAnchorable != null) diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs index 538008f9..0ab9d523 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorControl.cs @@ -105,14 +105,31 @@ namespace Xceed.Wpf.AvalonDock.Controls if (!e.Handled) { - _model.Root.Manager.ShowAutoHideWindow(this); - _model.IsActive = true; + if (_model.Root.Manager.AutoHideWindow.Visibility != Visibility.Visible) + { + _model.Root.Manager.ShowAutoHideWindow(this); + _model.IsActive = true; + _manuallyOpened = true; + } + else + { + if (!_inGracePeriod) + { + _model.Root.Manager.HideAutoHideWindow(this); + } + } } } DispatcherTimer _openUpTimer = null; + DispatcherTimer _clickGracePeriodTimer = null; + + bool _inGracePeriod = false; + + bool _manuallyOpened = false; + protected override void OnMouseEnter(System.Windows.Input.MouseEventArgs e) { base.OnMouseEnter(e); @@ -132,6 +149,30 @@ namespace Xceed.Wpf.AvalonDock.Controls _openUpTimer.Stop(); _openUpTimer = null; _model.Root.Manager.ShowAutoHideWindow(this); + + if (!_manuallyOpened) + { + _clickGracePeriodTimer = new DispatcherTimer(DispatcherPriority.ApplicationIdle); + _clickGracePeriodTimer.Interval = TimeSpan.FromMilliseconds(1000); + _inGracePeriod = true; + _clickGracePeriodTimer.Tick += new EventHandler(_clickGracePeriodTimer_Tick); + _clickGracePeriodTimer.Start(); + } + + _manuallyOpened = false; + } + + void _clickGracePeriodTimer_Tick(object sender, EventArgs e) + { + StopGraceTimer(); + } + + void StopGraceTimer() + { + _clickGracePeriodTimer.Tick -= new EventHandler(_clickGracePeriodTimer_Tick); + _clickGracePeriodTimer.Stop(); + _clickGracePeriodTimer = null; + _inGracePeriod = false; } protected override void OnMouseLeave(System.Windows.Input.MouseEventArgs e) diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs index 4545a0db..487685d1 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableFloatingWindowControl.cs @@ -51,6 +51,9 @@ namespace Xceed.Wpf.AvalonDock.Controls internal override void UpdateThemeResources( Xceed.Wpf.AvalonDock.Themes.Theme oldTheme = null ) { + if (Application.Current != null) + return; + base.UpdateThemeResources(oldTheme); if (_overlayWindow != null) @@ -141,6 +144,7 @@ namespace Xceed.Wpf.AvalonDock.Controls bool IOverlayWindowHost.HitTest(Point dragPoint) { + if (!this.IsVisible) return false; Rect detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); return detectionRect.Contains(dragPoint); } @@ -175,8 +179,11 @@ namespace Xceed.Wpf.AvalonDock.Controls void IOverlayWindowHost.HideOverlayWindow() { _dropAreas = null; + if (_overlayWindow != null) + { _overlayWindow.Owner = null; _overlayWindow.HideDropTargets(); + } } List _dropAreas = null; @@ -345,7 +352,7 @@ namespace Xceed.Wpf.AvalonDock.Controls foreach (var anchorable in this.Model.Descendents().OfType().ToArray()) { var anchorableLayoutItem = manager.GetLayoutItemFromModel(anchorable) as LayoutAnchorableItem; - anchorableLayoutItem.HideCommand.Execute(parameter); + anchorableLayoutItem.CloseCommand.Execute(parameter); } } #endregion diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs index 4a1a34d3..e5260bc2 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAnchorableItem.cs @@ -267,7 +267,8 @@ namespace Xceed.Wpf.AvalonDock.Controls { if (LayoutElement == null) return false; - return LayoutElement.FindParent() != null; + + return LayoutElement.CanDock && LayoutElement.FindParent() != null; } private void ExecuteDockCommand(object parameter) diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs index 2be0ffc9..b5ab5f5c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutAutoHideWindowControl.cs @@ -28,6 +28,7 @@ using System.Windows.Media; using Xceed.Wpf.AvalonDock.Layout; using System.Diagnostics; using System.Windows.Threading; +using System.ComponentModel; namespace Xceed.Wpf.AvalonDock.Controls { @@ -119,12 +120,23 @@ namespace Xceed.Wpf.AvalonDock.Controls protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { + // Make sure that autohide windows always display on top of other Controls + // (even Win32 control which WPF cannot normally overlay!) if (msg == Win32Helper.WM_WINDOWPOSCHANGING) { - if (_internalHost_ContentRendered) - Win32Helper.SetWindowPos(_internalHwndSource.Handle, Win32Helper.HWND_TOP, 0, 0, 0, 0, Win32Helper.SetWindowPosFlags.IgnoreMove | Win32Helper.SetWindowPosFlags.IgnoreResize); + // APD Fix - Stop a recursive call to WndProc when the window has been destroyed + // It was making a call to SetWindowPos which could cause a stack overflow. + if (_internalHost_ContentRendered) + { + Win32Helper.WINDOWPOS mwp = (Win32Helper.WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(Win32Helper.WINDOWPOS)); + + mwp.hwndInsertAfter = Win32Helper.HWND_TOP; + mwp.flags = mwp.flags & ~(int)Win32Helper.SetWindowPosFlags.IgnoreZOrder; + + Marshal.StructureToPtr(mwp, lParam, true); + } } - return base.WndProc(hwnd, msg, wParam, lParam, ref handled); + return base.WndProc(hwnd, msg, wParam, lParam, ref handled); } protected override void DestroyWindowCore(System.Runtime.InteropServices.HandleRef hwnd) @@ -478,23 +490,23 @@ namespace Xceed.Wpf.AvalonDock.Controls return base.ArrangeOverride(finalSize);// new Size(_internalHostPresenter.ActualWidth, _internalHostPresenter.ActualHeight); } - WeakReference _lastFocusedElement = null; - protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) - { - base.OnGotKeyboardFocus(e); - if (!e.Handled && _internalHostPresenter != null) - { - if (e.NewFocus == _internalHostPresenter) - { - var elementToFocus = _lastFocusedElement.GetValueOrDefault(); - if (elementToFocus != null) - Keyboard.Focus(elementToFocus); - e.Handled = true; - } - else - _lastFocusedElement = new WeakReference(e.NewFocus); - } - } + WeakReference _lastFocusedElement = null; + protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) + { + base.OnGotKeyboardFocus(e); + if (!e.Handled && _internalHostPresenter != null) + { + if (e.NewFocus == _internalHostPresenter) + { + var elementToFocus = _lastFocusedElement.GetValueOrDefault(); + if (elementToFocus != null) + Keyboard.Focus(elementToFocus); + e.Handled = true; + } + else + _lastFocusedElement = new WeakReference(e.NewFocus); + } + } #region Background diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs index b3e9d576..e1aca30d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutFloatingWindowControl.cs @@ -32,469 +32,487 @@ using Xceed.Wpf.AvalonDock.Themes; namespace Xceed.Wpf.AvalonDock.Controls { - public abstract class LayoutFloatingWindowControl : Window, ILayoutControl - { - static LayoutFloatingWindowControl() - { - LayoutFloatingWindowControl.ContentProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(null, null, new CoerceValueCallback(CoerceContentValue))); - AllowsTransparencyProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false)); - ShowInTaskbarProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false)); - } - - static object CoerceContentValue(DependencyObject sender, object content) - { - return new FloatingWindowContentHost(sender as LayoutFloatingWindowControl) { Content = content as UIElement }; - } - - protected class FloatingWindowContentHost : HwndHost - { - LayoutFloatingWindowControl _owner; - public FloatingWindowContentHost(LayoutFloatingWindowControl owner) - { - _owner = owner; - var manager = _owner.Model.Root.Manager; - } - - - HwndSource _wpfContentHost = null; - Border _rootPresenter = null; - DockingManager _manager = null; - - protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent) - { - _wpfContentHost = new HwndSource(new HwndSourceParameters() - { - ParentWindow = hwndParent.Handle, - WindowStyle = Win32Helper.WS_CHILD | Win32Helper.WS_VISIBLE | Win32Helper.WS_CLIPSIBLINGS | Win32Helper.WS_CLIPCHILDREN, - Width = 1, - Height = 1 - }); - - _rootPresenter = new Border() { Child = new AdornerDecorator() { Child = Content }, Focusable = true }; - _rootPresenter.SetBinding(Border.BackgroundProperty, new Binding("Background") { Source = _owner }); - _wpfContentHost.RootVisual = _rootPresenter; - _wpfContentHost.SizeToContent = SizeToContent.Manual; - _manager = _owner.Model.Root.Manager; - _manager.InternalAddLogicalChild(_rootPresenter); - - return new HandleRef(this, _wpfContentHost.Handle); - } - - - protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) - { - Trace.WriteLine("FloatingWindowContentHost.GotKeyboardFocus"); - base.OnGotKeyboardFocus(e); - } - protected override void DestroyWindowCore(HandleRef hwnd) - { - _manager.InternalRemoveLogicalChild(_rootPresenter); - if (_wpfContentHost != null) - { - _wpfContentHost.Dispose(); - _wpfContentHost = null; - } - } - protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) - { - switch (msg) - { - case Win32Helper.WM_SETFOCUS: - Trace.WriteLine("FloatingWindowContentHost.WM_SETFOCUS"); - break; - case Win32Helper.WM_KILLFOCUS: - Trace.WriteLine("FloatingWindowContentHost.WM_KILLFOCUS"); - break; - } - return base.WndProc(hwnd, msg, wParam, lParam, ref handled); - } - - public Visual RootVisual - { - get { return _rootPresenter; } - } - - protected override Size MeasureOverride(Size constraint) - { - if (Content == null) - return base.MeasureOverride(constraint); - - Content.Measure(constraint); - return Content.DesiredSize; - } - - #region Content - - /// - /// Content Dependency Property - /// - public static readonly DependencyProperty ContentProperty = - DependencyProperty.Register("Content", typeof(UIElement), typeof(FloatingWindowContentHost), - new FrameworkPropertyMetadata((UIElement)null, - new PropertyChangedCallback(OnContentChanged))); - - /// - /// Gets or sets the Content property. This dependency property - /// indicates .... - /// - public UIElement Content - { - get { return (UIElement)GetValue(ContentProperty); } - set { SetValue(ContentProperty, value); } - } - - /// - /// Handles changes to the Content property. - /// - private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((FloatingWindowContentHost)d).OnContentChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the Content property. - /// - protected virtual void OnContentChanged(DependencyPropertyChangedEventArgs e) - { - if (_rootPresenter != null) - _rootPresenter.Child = Content; - } - - #endregion - } - - ILayoutElement _model; - - protected LayoutFloatingWindowControl(ILayoutElement model) - { - this.Loaded += new RoutedEventHandler(OnLoaded); - this.Unloaded += new RoutedEventHandler(OnUnloaded); - _model = model; - UpdateThemeResources(); - } - - internal virtual void UpdateThemeResources(Theme oldTheme = null) - { - if (oldTheme != null) - { - var resourceDictionaryToRemove = - Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); - if (resourceDictionaryToRemove != null) - Resources.MergedDictionaries.Remove( - resourceDictionaryToRemove); - } - - var manager = _model.Root.Manager; - if (manager.Theme != null) - { - Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = manager.Theme.GetResourceUri() }); - } - } - - protected override void OnClosed(EventArgs e) - { - if (Content != null) - { - var host = Content as FloatingWindowContentHost; - host.Dispose(); - - if (_hwndSrc != null) - { - _hwndSrc.RemoveHook(_hwndSrcHook); - _hwndSrc.Dispose(); - _hwndSrc = null; - } - } - - base.OnClosed(e); - } - - bool _attachDrag = false; - internal void AttachDrag(bool onActivated = true) - { - if (onActivated) - { - _attachDrag = true; - this.Activated += new EventHandler(OnActivated); - } - else - { - IntPtr windowHandle = new WindowInteropHelper(this).Handle; - IntPtr lParam = new IntPtr(((int)Left & (int)0xFFFF) | (((int)Top) << 16)); - Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam); - } - } - - HwndSource _hwndSrc; - HwndSourceHook _hwndSrcHook; - - void OnLoaded(object sender, RoutedEventArgs e) - { - this.Loaded -= new RoutedEventHandler(OnLoaded); - - this.SetParentToMainWindowOf(Model.Root.Manager); - - - _hwndSrc = HwndSource.FromDependencyObject(this) as HwndSource; - _hwndSrcHook = new HwndSourceHook(FilterMessage); - _hwndSrc.AddHook(_hwndSrcHook); - } - - void OnUnloaded(object sender, RoutedEventArgs e) - { - this.Unloaded -= new RoutedEventHandler(OnUnloaded); - - if (_hwndSrc != null) - { - _hwndSrc.RemoveHook(_hwndSrcHook); - _hwndSrc.Dispose(); - _hwndSrc = null; - } - } - - void OnActivated(object sender, EventArgs e) - { - this.Activated -= new EventHandler(OnActivated); - - if (_attachDrag && Mouse.LeftButton == MouseButtonState.Pressed) - { - IntPtr windowHandle = new WindowInteropHelper(this).Handle; - var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); - var clientArea = Win32Helper.GetClientRect(windowHandle); - var windowArea = Win32Helper.GetWindowRect(windowHandle); - - Left = mousePosition.X - windowArea.Width / 2.0; - Top = mousePosition.Y - (windowArea.Height - clientArea.Height) / 2.0; - _attachDrag = false; - - IntPtr lParam = new IntPtr(((int)mousePosition.X & (int)0xFFFF) | (((int)mousePosition.Y) << 16)); - Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam); - } - } - - - protected override void OnInitialized(EventArgs e) - { - CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.CloseWindowCommand, - new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.CloseWindow((Window)args.Parameter)))); - CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MaximizeWindowCommand, - new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MaximizeWindow((Window)args.Parameter)))); - CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MinimizeWindowCommand, - new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MinimizeWindow((Window)args.Parameter)))); - CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.RestoreWindowCommand, - new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.RestoreWindow((Window)args.Parameter)))); - //Debug.Assert(this.Owner != null); - base.OnInitialized(e); - } - - public abstract ILayoutElement Model { get; } - - - #region IsDragging - - /// - /// IsDragging Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey IsDraggingPropertyKey - = DependencyProperty.RegisterReadOnly("IsDragging", typeof(bool), typeof(LayoutFloatingWindowControl), - new FrameworkPropertyMetadata((bool)false, - new PropertyChangedCallback(OnIsDraggingChanged))); - - public static readonly DependencyProperty IsDraggingProperty - = IsDraggingPropertyKey.DependencyProperty; - - /// - /// Gets the IsDragging property. This dependency property - /// indicates that this floating window is being dragged. - /// - public bool IsDragging - { - get { return (bool)GetValue(IsDraggingProperty); } - } - - /// - /// Provides a secure method for setting the IsDragging property. - /// This dependency property indicates that this floating window is being dragged. - /// - /// The new value for the property. - protected void SetIsDragging(bool value) - { - SetValue(IsDraggingPropertyKey, value); - } - - /// - /// Handles changes to the IsDragging property. - /// - private static void OnIsDraggingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((LayoutFloatingWindowControl)d).OnIsDraggingChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the IsDragging property. - /// - protected virtual void OnIsDraggingChanged(DependencyPropertyChangedEventArgs e) - { - //Trace.WriteLine("IsDragging={0}", e.NewValue); - } - - #endregion - - - - DragService _dragService = null; - - void UpdatePositionAndSizeOfPanes() - { - foreach (var posElement in Model.Descendents().OfType()) - { - posElement.FloatingLeft = Left; - posElement.FloatingTop = Top; - posElement.FloatingWidth = Width; - posElement.FloatingHeight = Height; - posElement.IsMaximized = this.WindowState == System.Windows.WindowState.Maximized; - } - } - - protected virtual IntPtr FilterMessage( - IntPtr hwnd, - int msg, - IntPtr wParam, - IntPtr lParam, - ref bool handled - ) - { - handled = false; - - switch (msg) - { - case Win32Helper.WM_ACTIVATE: - if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE) - { - if (lParam == this.GetParentWindowHandle()) - { - Win32Helper.SetActiveWindow(_hwndSrc.Handle); - handled = true; - } - } - break; - case Win32Helper.WM_EXITSIZEMOVE: - UpdatePositionAndSizeOfPanes(); - - if (_dragService != null) - { - bool dropFlag; - var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); - _dragService.Drop(mousePosition, out dropFlag); - _dragService = null; - SetIsDragging(false); - - if (dropFlag) - InternalClose(); - } - - break; - case Win32Helper.WM_MOVING: - { - UpdateDragPosition(); - } - break; - case Win32Helper.WM_LBUTTONUP: //set as handled right button click on title area (after showing context menu) - if (_dragService != null && Mouse.LeftButton == MouseButtonState.Released) - { - _dragService.Abort(); - _dragService = null; - SetIsDragging(false); - } - break; - } - - - - return IntPtr.Zero; - } - - private void UpdateDragPosition() - { - if (_dragService == null) - { - _dragService = new DragService(this); - SetIsDragging(true); - } - - var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); - _dragService.UpdateMouseLocation(mousePosition); - } - - bool _internalCloseFlag = false; - - internal void InternalClose() - { - _internalCloseFlag = true; - Close(); - } - - - protected bool CloseInitiatedByUser - { - get { return !_internalCloseFlag; } - } - - internal bool KeepContentVisibleOnClose - { - get; - set; - } - - protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) - { - base.OnMouseLeftButtonUp(e); - } - - #region IsMaximized - - /// - /// IsMaximized Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey IsMaximizedPropertyKey - = DependencyProperty.RegisterReadOnly("IsMaximized", typeof(bool), typeof(LayoutFloatingWindowControl), - new FrameworkPropertyMetadata((bool)false)); - - public static readonly DependencyProperty IsMaximizedProperty - = IsMaximizedPropertyKey.DependencyProperty; - - /// - /// Gets the IsMaximized property. This dependency property - /// indicates if the window is maximized. - /// - public bool IsMaximized - { - get { return (bool)GetValue(IsMaximizedProperty); } - } - - /// - /// Provides a secure method for setting the IsMaximized property. - /// This dependency property indicates if the window is maximized. - /// - /// The new value for the property. - protected void SetIsMaximized(bool value) - { - SetValue(IsMaximizedPropertyKey, value); - } - - protected override void OnStateChanged(EventArgs e) - { - SetIsMaximized(WindowState == System.Windows.WindowState.Maximized); - base.OnStateChanged(e); - } - - #endregion + public abstract class LayoutFloatingWindowControl : Window, ILayoutControl + { + static LayoutFloatingWindowControl() + { + LayoutFloatingWindowControl.ContentProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(null, null, new CoerceValueCallback(CoerceContentValue))); + AllowsTransparencyProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false)); + ShowInTaskbarProperty.OverrideMetadata(typeof(LayoutFloatingWindowControl), new FrameworkPropertyMetadata(false)); + } + + static object CoerceContentValue(DependencyObject sender, object content) + { + return new FloatingWindowContentHost(sender as LayoutFloatingWindowControl) { Content = content as UIElement }; + } + + protected class FloatingWindowContentHost : HwndHost + { + LayoutFloatingWindowControl _owner; + public FloatingWindowContentHost(LayoutFloatingWindowControl owner) + { + _owner = owner; + var manager = _owner.Model.Root.Manager; + } + + + HwndSource _wpfContentHost = null; + Border _rootPresenter = null; + DockingManager _manager = null; + + protected override System.Runtime.InteropServices.HandleRef BuildWindowCore(System.Runtime.InteropServices.HandleRef hwndParent) + { + _wpfContentHost = new HwndSource(new HwndSourceParameters() + { + ParentWindow = hwndParent.Handle, + WindowStyle = Win32Helper.WS_CHILD | Win32Helper.WS_VISIBLE | Win32Helper.WS_CLIPSIBLINGS | Win32Helper.WS_CLIPCHILDREN, + Width = 1, + Height = 1 + }); + + _rootPresenter = new Border() { Child = new AdornerDecorator() { Child = Content }, Focusable = true }; + _rootPresenter.SetBinding(Border.BackgroundProperty, new Binding("Background") { Source = _owner }); + _wpfContentHost.RootVisual = _rootPresenter; + _wpfContentHost.SizeToContent = SizeToContent.Manual; + _manager = _owner.Model.Root.Manager; + _manager.InternalAddLogicalChild(_rootPresenter); + + return new HandleRef(this, _wpfContentHost.Handle); + } + + + protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e) + { + Trace.WriteLine("FloatingWindowContentHost.GotKeyboardFocus"); + base.OnGotKeyboardFocus(e); + } + protected override void DestroyWindowCore(HandleRef hwnd) + { + _manager.InternalRemoveLogicalChild(_rootPresenter); + if (_wpfContentHost != null) + { + _wpfContentHost.Dispose(); + _wpfContentHost = null; + } + } + protected override IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) + { + switch (msg) + { + case Win32Helper.WM_SETFOCUS: + Trace.WriteLine("FloatingWindowContentHost.WM_SETFOCUS"); + break; + case Win32Helper.WM_KILLFOCUS: + Trace.WriteLine("FloatingWindowContentHost.WM_KILLFOCUS"); + break; + } + return base.WndProc(hwnd, msg, wParam, lParam, ref handled); + } + + public Visual RootVisual + { + get { return _rootPresenter; } + } + + protected override Size MeasureOverride(Size constraint) + { + if (Content == null) + return base.MeasureOverride(constraint); + + Content.Measure(constraint); + return Content.DesiredSize; + } + + #region Content + + /// + /// Content Dependency Property + /// + public static readonly DependencyProperty ContentProperty = + DependencyProperty.Register("Content", typeof(UIElement), typeof(FloatingWindowContentHost), + new FrameworkPropertyMetadata((UIElement)null, + new PropertyChangedCallback(OnContentChanged))); + + /// + /// Gets or sets the Content property. This dependency property + /// indicates .... + /// + public UIElement Content + { + get { return (UIElement)GetValue(ContentProperty); } + set { SetValue(ContentProperty, value); } + } + + /// + /// Handles changes to the Content property. + /// + private static void OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((FloatingWindowContentHost)d).OnContentChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the Content property. + /// + protected virtual void OnContentChanged(DependencyPropertyChangedEventArgs e) + { + if (_rootPresenter != null) + _rootPresenter.Child = Content; + } + + #endregion + } + + ILayoutElement _model; + + protected LayoutFloatingWindowControl(ILayoutElement model) + { + this.Loaded += new RoutedEventHandler(OnLoaded); + this.Unloaded += new RoutedEventHandler(OnUnloaded); + _model = model; + UpdateThemeResources(); + } + + internal virtual void UpdateThemeResources(Theme oldTheme = null) + { + if (Application.Current != null) + return; + + if (oldTheme != null) + { + var resourceDictionaryToRemove = + Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); + if (resourceDictionaryToRemove != null) + Resources.MergedDictionaries.Remove( + resourceDictionaryToRemove); + } + + var manager = _model.Root.Manager; + if (manager.Theme != null) + { + Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = manager.Theme.GetResourceUri() }); + } + } + + protected override void OnClosed(EventArgs e) + { + if (Content != null) + { + var host = Content as FloatingWindowContentHost; + host.Dispose(); + + if (_hwndSrc != null) + { + _hwndSrc.RemoveHook(_hwndSrcHook); + _hwndSrc.Dispose(); + _hwndSrc = null; + } + } + + base.OnClosed(e); + } + + bool _attachDrag = false; + internal void AttachDrag(bool onActivated = true) + { + if (onActivated) + { + _attachDrag = true; + this.Activated += new EventHandler(OnActivated); + } + else + { + IntPtr windowHandle = new WindowInteropHelper(this).Handle; + IntPtr lParam = new IntPtr(((int)Left & (int)0xFFFF) | (((int)Top) << 16)); + Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam); + } + } + + HwndSource _hwndSrc; + HwndSourceHook _hwndSrcHook; + + void OnLoaded(object sender, RoutedEventArgs e) + { + this.Loaded -= new RoutedEventHandler(OnLoaded); + + this.SetParentToMainWindowOf(Model.Root.Manager); + + + _hwndSrc = HwndSource.FromDependencyObject(this) as HwndSource; + _hwndSrcHook = new HwndSourceHook(FilterMessage); + _hwndSrc.AddHook(_hwndSrcHook); + } + + void OnUnloaded(object sender, RoutedEventArgs e) + { + this.Unloaded -= new RoutedEventHandler(OnUnloaded); + + if (_hwndSrc != null) + { + _hwndSrc.RemoveHook(_hwndSrcHook); + _hwndSrc.Dispose(); + _hwndSrc = null; + } + } + + void OnActivated(object sender, EventArgs e) + { + this.Activated -= new EventHandler(OnActivated); + + if (_attachDrag && Mouse.LeftButton == MouseButtonState.Pressed) + { + IntPtr windowHandle = new WindowInteropHelper(this).Handle; + var mousePosition = this.PointToScreenDPI(Mouse.GetPosition(this)); + var clientArea = Win32Helper.GetClientRect(windowHandle); + var windowArea = Win32Helper.GetWindowRect(windowHandle); + + Left = mousePosition.X - windowArea.Width / 2.0; + Top = mousePosition.Y - (windowArea.Height - clientArea.Height) / 2.0; + _attachDrag = false; + + IntPtr lParam = new IntPtr(((int)mousePosition.X & (int)0xFFFF) | (((int)mousePosition.Y) << 16)); + Win32Helper.SendMessage(windowHandle, Win32Helper.WM_NCLBUTTONDOWN, new IntPtr(Win32Helper.HT_CAPTION), lParam); + } + } + + + protected override void OnInitialized(EventArgs e) + { + CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.CloseWindowCommand, + new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.CloseWindow((Window)args.Parameter)))); + CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MaximizeWindowCommand, + new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MaximizeWindow((Window)args.Parameter)))); + CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.MinimizeWindowCommand, + new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.MinimizeWindow((Window)args.Parameter)))); + CommandBindings.Add(new CommandBinding(Microsoft.Windows.Shell.SystemCommands.RestoreWindowCommand, + new ExecutedRoutedEventHandler((s, args) => Microsoft.Windows.Shell.SystemCommands.RestoreWindow((Window)args.Parameter)))); + //Debug.Assert(this.Owner != null); + base.OnInitialized(e); + } + + public abstract ILayoutElement Model { get; } + + + #region IsDragging + + /// + /// IsDragging Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey IsDraggingPropertyKey + = DependencyProperty.RegisterReadOnly("IsDragging", typeof(bool), typeof(LayoutFloatingWindowControl), + new FrameworkPropertyMetadata((bool)false, + new PropertyChangedCallback(OnIsDraggingChanged))); + + public static readonly DependencyProperty IsDraggingProperty + = IsDraggingPropertyKey.DependencyProperty; + + /// + /// Gets the IsDragging property. This dependency property + /// indicates that this floating window is being dragged. + /// + public bool IsDragging + { + get { return (bool)GetValue(IsDraggingProperty); } + } + + /// + /// Provides a secure method for setting the IsDragging property. + /// This dependency property indicates that this floating window is being dragged. + /// + /// The new value for the property. + protected void SetIsDragging(bool value) + { + SetValue(IsDraggingPropertyKey, value); + } + + /// + /// Handles changes to the IsDragging property. + /// + private static void OnIsDraggingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((LayoutFloatingWindowControl)d).OnIsDraggingChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the IsDragging property. + /// + protected virtual void OnIsDraggingChanged(DependencyPropertyChangedEventArgs e) + { + //Trace.WriteLine("IsDragging={0}", e.NewValue); + } + + #endregion + + + + DragService _dragService = null; + + void UpdatePositionAndSizeOfPanes() + { + foreach (var posElement in Model.Descendents().OfType()) + { + posElement.FloatingLeft = Left; + posElement.FloatingTop = Top; + posElement.FloatingWidth = Width; + posElement.FloatingHeight = Height; + } + } + + void UpdateMaximizedState(bool isMaximized) + { + foreach (var posElement in Model.Descendents().OfType()) + { + posElement.IsMaximized = isMaximized; + } + } + + protected virtual IntPtr FilterMessage( + IntPtr hwnd, + int msg, + IntPtr wParam, + IntPtr lParam, + ref bool handled + ) + { + handled = false; + + switch (msg) + { + case Win32Helper.WM_ACTIVATE: + if (((int)wParam & 0xFFFF) == Win32Helper.WA_INACTIVE) + { + if (lParam == this.GetParentWindowHandle()) + { + Win32Helper.SetActiveWindow(_hwndSrc.Handle); + handled = true; + } + } + break; + case Win32Helper.WM_EXITSIZEMOVE: + UpdatePositionAndSizeOfPanes(); + + if (_dragService != null) + { + bool dropFlag; + var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); + _dragService.Drop(mousePosition, out dropFlag); + _dragService = null; + SetIsDragging(false); + + if (dropFlag) + InternalClose(); + } + + break; + case Win32Helper.WM_MOVING: + { + UpdateDragPosition(); + } + break; + case Win32Helper.WM_LBUTTONUP: //set as handled right button click on title area (after showing context menu) + if (_dragService != null && Mouse.LeftButton == MouseButtonState.Released) + { + _dragService.Abort(); + _dragService = null; + SetIsDragging(false); + } + break; + case Win32Helper.WM_SYSCOMMAND: + IntPtr wMaximize = new IntPtr(Win32Helper.SC_MAXIMIZE); + IntPtr wRestore = new IntPtr(Win32Helper.SC_RESTORE); + if (wParam == wMaximize || wParam == wRestore) + { + UpdateMaximizedState(wParam == wMaximize); + } + break; + } + + + + return IntPtr.Zero; + } + + private void UpdateDragPosition() + { + if (_dragService == null) + { + _dragService = new DragService(this); + SetIsDragging(true); + } + + var mousePosition = this.TransformToDeviceDPI(Win32Helper.GetMousePosition()); + _dragService.UpdateMouseLocation(mousePosition); + } + + bool _internalCloseFlag = false; + + internal void InternalClose() + { + _internalCloseFlag = true; + Close(); + } + + + protected bool CloseInitiatedByUser + { + get { return !_internalCloseFlag; } + } + + internal bool KeepContentVisibleOnClose + { + get; + set; + } + + protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e) + { + base.OnMouseLeftButtonUp(e); + } + + #region IsMaximized + + /// + /// IsMaximized Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey IsMaximizedPropertyKey + = DependencyProperty.RegisterReadOnly("IsMaximized", typeof(bool), typeof(LayoutFloatingWindowControl), + new FrameworkPropertyMetadata((bool)false)); + + public static readonly DependencyProperty IsMaximizedProperty + = IsMaximizedPropertyKey.DependencyProperty; + + /// + /// Gets the IsMaximized property. This dependency property + /// indicates if the window is maximized. + /// + public bool IsMaximized + { + get { return (bool)GetValue(IsMaximizedProperty); } + } + + /// + /// Provides a secure method for setting the IsMaximized property. + /// This dependency property indicates if the window is maximized. + /// + /// The new value for the property. + protected void SetIsMaximized(bool value) + { + SetValue(IsMaximizedPropertyKey, value); + } + + protected override void OnStateChanged(EventArgs e) + { + SetIsMaximized(WindowState == System.Windows.WindowState.Maximized); + base.OnStateChanged(e); + } + + #endregion + + + + + - - - - - - } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs index c70b179b..59cfa8b4 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutGridControl.cs @@ -525,6 +525,7 @@ namespace Xceed.Wpf.AvalonDock.Controls _resizerWindowHost = new Window() { + SizeToContent = System.Windows.SizeToContent.Manual, ResizeMode = ResizeMode.NoResize, WindowStyle = System.Windows.WindowStyle.None, ShowInTaskbar = false, diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs index 2b19c27d..b1cd8e7d 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/LayoutItem.cs @@ -523,6 +523,31 @@ namespace Xceed.Wpf.AvalonDock.Controls #endregion + #region CanDock + + public static readonly DependencyProperty CanDockProperty = + DependencyProperty.Register("CanDock", typeof(bool), typeof(LayoutItem), + new FrameworkPropertyMetadata(true, + new PropertyChangedCallback(OnCanDockChanged))); + + public bool CanDock + { + get { return (bool)GetValue(CanDockProperty); } + set { SetValue(CanDockProperty, value); } + } + + private static void OnCanDockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((LayoutItem)d).OnCanDockChanged(e); + } + + protected virtual void OnCanDockChanged(DependencyPropertyChangedEventArgs e) + { + LayoutElement.CanDock = (bool)e.NewValue; + } + + #endregion + #region CloseCommand /// @@ -570,10 +595,10 @@ namespace Xceed.Wpf.AvalonDock.Controls private bool CanExecuteCloseCommand(object parameter) { #if DEBUG - if( LayoutElement != null ) - System.Diagnostics.Trace.WriteLine( string.Format( "CanExecuteCloseCommand({0}) = {1}", LayoutElement.Title, LayoutElement.CanClose ) ); + if( LayoutElement != null ) + System.Diagnostics.Trace.WriteLine( string.Format( "CanExecuteCloseCommand({0}) = {1}", LayoutElement.Title, LayoutElement.CanClose ) ); #endif - return LayoutElement != null && LayoutElement.CanClose; + return LayoutElement != null && LayoutElement.CanClose; } private void ExecuteCloseCommand(object parameter) @@ -694,7 +719,7 @@ namespace Xceed.Wpf.AvalonDock.Controls private bool CanExecuteDockAsDocumentCommand(object parameter) { - return LayoutElement != null && LayoutElement.FindParent() == null; + return LayoutElement != null && LayoutElement.CanDock && LayoutElement.FindParent() == null; } private void ExecuteDockAsDocumentCommand(object parameter) diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs index 5ec38eb1..fd5f5a8c 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/NavigatorWindow.cs @@ -59,6 +59,9 @@ namespace Xceed.Wpf.AvalonDock.Controls internal void UpdateThemeResources(Theme oldTheme = null) { + if (Application.Current != null) + return; + if (oldTheme != null) { var resourceDictionaryToRemove = diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs index 6010ac42..c6d81798 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Controls/OverlayWindow.cs @@ -28,533 +28,546 @@ using Xceed.Wpf.AvalonDock.Themes; namespace Xceed.Wpf.AvalonDock.Controls { - public class OverlayWindow : Window, IOverlayWindow - { - static OverlayWindow() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(typeof(OverlayWindow))); - - OverlayWindow.AllowsTransparencyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(true)); - OverlayWindow.WindowStyleProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(WindowStyle.None)); - OverlayWindow.ShowInTaskbarProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); - OverlayWindow.ShowActivatedProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); - OverlayWindow.VisibilityProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(Visibility.Hidden)); - } - - - internal OverlayWindow(IOverlayWindowHost host) - { - _host = host; - UpdateThemeResources(); - } - - - internal void UpdateThemeResources(Theme oldTheme = null) - { - if (oldTheme != null) - { - var resourceDictionaryToRemove = - Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); - if (resourceDictionaryToRemove != null) - Resources.MergedDictionaries.Remove( - resourceDictionaryToRemove); - } - - if (_host.Manager.Theme != null) - { - Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() }); - } - } - - - Canvas _mainCanvasPanel; - Grid _gridDockingManagerDropTargets; - Grid _gridAnchorablePaneDropTargets; - Grid _gridDocumentPaneDropTargets; - Grid _gridDocumentPaneFullDropTargets; - - FrameworkElement _dockingManagerDropTargetBottom; - FrameworkElement _dockingManagerDropTargetTop; - FrameworkElement _dockingManagerDropTargetLeft; - FrameworkElement _dockingManagerDropTargetRight; - - FrameworkElement _anchorablePaneDropTargetBottom; - FrameworkElement _anchorablePaneDropTargetTop; - FrameworkElement _anchorablePaneDropTargetLeft; - FrameworkElement _anchorablePaneDropTargetRight; - FrameworkElement _anchorablePaneDropTargetInto; - - FrameworkElement _documentPaneDropTargetBottom; - FrameworkElement _documentPaneDropTargetTop; - FrameworkElement _documentPaneDropTargetLeft; - FrameworkElement _documentPaneDropTargetRight; - FrameworkElement _documentPaneDropTargetInto; - - FrameworkElement _documentPaneDropTargetBottomAsAnchorablePane; - FrameworkElement _documentPaneDropTargetTopAsAnchorablePane; - FrameworkElement _documentPaneDropTargetLeftAsAnchorablePane; - FrameworkElement _documentPaneDropTargetRightAsAnchorablePane; - - FrameworkElement _documentPaneFullDropTargetBottom; - FrameworkElement _documentPaneFullDropTargetTop; - FrameworkElement _documentPaneFullDropTargetLeft; - FrameworkElement _documentPaneFullDropTargetRight; - FrameworkElement _documentPaneFullDropTargetInto; - - Path _previewBox; - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - _mainCanvasPanel = GetTemplateChild("PART_DropTargetsContainer") as Canvas; - _gridDockingManagerDropTargets = GetTemplateChild("PART_DockingManagerDropTargets") as Grid; - _gridAnchorablePaneDropTargets = GetTemplateChild("PART_AnchorablePaneDropTargets") as Grid; - _gridDocumentPaneDropTargets = GetTemplateChild("PART_DocumentPaneDropTargets") as Grid; - _gridDocumentPaneFullDropTargets = GetTemplateChild("PART_DocumentPaneFullDropTargets") as Grid; - - _gridDockingManagerDropTargets.Visibility = System.Windows.Visibility.Hidden; - _gridAnchorablePaneDropTargets.Visibility = System.Windows.Visibility.Hidden; - _gridDocumentPaneDropTargets.Visibility = System.Windows.Visibility.Hidden; - if (_gridDocumentPaneFullDropTargets != null) - _gridDocumentPaneFullDropTargets.Visibility = System.Windows.Visibility.Hidden; - - _dockingManagerDropTargetBottom = GetTemplateChild("PART_DockingManagerDropTargetBottom") as FrameworkElement; - _dockingManagerDropTargetTop = GetTemplateChild("PART_DockingManagerDropTargetTop") as FrameworkElement; - _dockingManagerDropTargetLeft = GetTemplateChild("PART_DockingManagerDropTargetLeft") as FrameworkElement; - _dockingManagerDropTargetRight = GetTemplateChild("PART_DockingManagerDropTargetRight") as FrameworkElement; - - _anchorablePaneDropTargetBottom = GetTemplateChild("PART_AnchorablePaneDropTargetBottom") as FrameworkElement; - _anchorablePaneDropTargetTop = GetTemplateChild("PART_AnchorablePaneDropTargetTop") as FrameworkElement; - _anchorablePaneDropTargetLeft = GetTemplateChild("PART_AnchorablePaneDropTargetLeft") as FrameworkElement; - _anchorablePaneDropTargetRight = GetTemplateChild("PART_AnchorablePaneDropTargetRight") as FrameworkElement; - _anchorablePaneDropTargetInto = GetTemplateChild("PART_AnchorablePaneDropTargetInto") as FrameworkElement; - - _documentPaneDropTargetBottom = GetTemplateChild("PART_DocumentPaneDropTargetBottom") as FrameworkElement; - _documentPaneDropTargetTop = GetTemplateChild("PART_DocumentPaneDropTargetTop") as FrameworkElement; - _documentPaneDropTargetLeft = GetTemplateChild("PART_DocumentPaneDropTargetLeft") as FrameworkElement; - _documentPaneDropTargetRight = GetTemplateChild("PART_DocumentPaneDropTargetRight") as FrameworkElement; - _documentPaneDropTargetInto = GetTemplateChild("PART_DocumentPaneDropTargetInto") as FrameworkElement; - - _documentPaneDropTargetBottomAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetBottomAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetTopAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetTopAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetLeftAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetLeftAsAnchorablePane") as FrameworkElement; - _documentPaneDropTargetRightAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetRightAsAnchorablePane") as FrameworkElement; - - _documentPaneFullDropTargetBottom = GetTemplateChild("PART_DocumentPaneFullDropTargetBottom") as FrameworkElement; - _documentPaneFullDropTargetTop = GetTemplateChild("PART_DocumentPaneFullDropTargetTop") as FrameworkElement; - _documentPaneFullDropTargetLeft = GetTemplateChild("PART_DocumentPaneFullDropTargetLeft") as FrameworkElement; - _documentPaneFullDropTargetRight = GetTemplateChild("PART_DocumentPaneFullDropTargetRight") as FrameworkElement; - _documentPaneFullDropTargetInto = GetTemplateChild("PART_DocumentPaneFullDropTargetInto") as FrameworkElement; - - _previewBox = GetTemplateChild("PART_PreviewBox") as Path; - } - - - internal void EnableDropTargets() - { - //Trace.WriteLine("EnableDropTargets()"); - if (_mainCanvasPanel != null) - _mainCanvasPanel.Visibility = System.Windows.Visibility.Visible; - } - - internal void HideDropTargets() - { - //Trace.WriteLine("HideDropTargets()"); - if (_mainCanvasPanel != null) - _mainCanvasPanel.Visibility = System.Windows.Visibility.Hidden; - - } - - IOverlayWindowHost _host; - - IEnumerable IOverlayWindow.GetTargets() - { - foreach (var visibleArea in _visibleAreas) - { - switch (visibleArea.Type) - { - case DropAreaType.DockingManager: - { - var dropAreaDockingManager = visibleArea as DropArea; - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetLeft.GetScreenArea(), DropTargetType.DockingManagerDockLeft); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetTop.GetScreenArea(), DropTargetType.DockingManagerDockTop); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetBottom.GetScreenArea(), DropTargetType.DockingManagerDockBottom); - yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetRight.GetScreenArea(), DropTargetType.DockingManagerDockRight); - } - break; - case DropAreaType.AnchorablePane: - { - var dropAreaAnchorablePane = visibleArea as DropArea; - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetLeft.GetScreenArea(), DropTargetType.AnchorablePaneDockLeft); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetTop.GetScreenArea(), DropTargetType.AnchorablePaneDockTop); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetRight.GetScreenArea(), DropTargetType.AnchorablePaneDockRight); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetBottom.GetScreenArea(), DropTargetType.AnchorablePaneDockBottom); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetInto.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); - - var parentPaneModel = dropAreaAnchorablePane.AreaElement.Model as LayoutAnchorablePane; - LayoutAnchorableTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaAnchorablePane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model as LayoutAnchorable; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.AnchorablePaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaAnchorablePane.AreaElement.GetScreenArea().Right) - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, newAreaTabItemScreenArea, DropTargetType.AnchorablePaneDockInside, parentPaneModel.Children.Count); - } - - var dropAreaTitle = dropAreaAnchorablePane.AreaElement.FindVisualChildren().FirstOrDefault(); - if (dropAreaTitle != null) - yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTitle.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); - } - break; - case DropAreaType.DocumentPane: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - { - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneFullDropTargetLeft.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); - if (_documentPaneFullDropTargetTop.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); - if (_documentPaneFullDropTargetRight.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); - if (_documentPaneFullDropTargetBottom.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); - if (_documentPaneFullDropTargetInto.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); - - var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; - LayoutDocumentTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); - } - - if (_documentPaneDropTargetLeftAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeftAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableLeft); - if (_documentPaneDropTargetTopAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTopAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableTop); - if (_documentPaneDropTargetRightAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRightAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableRight); - if (_documentPaneDropTargetBottomAsAnchorablePane.IsVisible) - yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottomAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableBottom); - } - else - { - - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneDropTargetLeft.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); - if (_documentPaneDropTargetTop.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); - if (_documentPaneDropTargetRight.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); - if (_documentPaneDropTargetBottom.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); - if (_documentPaneDropTargetInto.IsVisible) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); - - var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; - LayoutDocumentTabItem lastAreaTabItem = null; - foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) - { - var tabItemModel = dropAreaTabItem.Model; - lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? - dropAreaTabItem : lastAreaTabItem; - int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); - } - - if (lastAreaTabItem != null) - { - var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); - var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); - if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) - yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); - } - } - } - break; - case DropAreaType.DocumentPaneGroup: - { - var dropAreaDocumentPane = visibleArea as DropArea; - if (_documentPaneDropTargetInto.IsVisible) - yield return new DocumentPaneGroupDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneGroupDockInside); - } - break; - } - - } - yield break; - } - - LayoutFloatingWindowControl _floatingWindow = null; - void IOverlayWindow.DragEnter(LayoutFloatingWindowControl floatingWindow) - { - _floatingWindow = floatingWindow; - EnableDropTargets(); - } - - void IOverlayWindow.DragLeave(LayoutFloatingWindowControl floatingWindow) - { - Visibility = System.Windows.Visibility.Hidden; - _floatingWindow = null; - } - - protected override void OnClosing(System.ComponentModel.CancelEventArgs e) - { - base.OnClosing(e); - } - - - List _visibleAreas = new List(); - void IOverlayWindow.DragEnter(IDropArea area) - { - _visibleAreas.Add(area); - - FrameworkElement areaElement; - switch (area.Type) - { - case DropAreaType.DockingManager: - areaElement = _gridDockingManagerDropTargets; - break; - case DropAreaType.AnchorablePane: - areaElement = _gridAnchorablePaneDropTargets; - break; - case DropAreaType.DocumentPaneGroup: - { - areaElement = _gridDocumentPaneDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = (dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPaneGroup).Children.First() as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; - } - break; - case DropAreaType.DocumentPane: - default: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - { - areaElement = _gridDocumentPaneFullDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneFullDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - _documentPaneFullDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - } - else - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; - _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; - } - } - else if (parentDocumentPaneGroup == null && - layoutDocumentPane != null && - layoutDocumentPane.ChildrenCount == 0) - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Hidden; - } - else - { - _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; - _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; - _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; - } - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - int indexOfDocumentPane = parentDocumentPaneGroup.Children.Where(ch => ch.IsVisible).ToList().IndexOf(layoutDocumentPane); - bool isFirstChild = indexOfDocumentPane == 0; - bool isLastChild = indexOfDocumentPane == parentDocumentPaneGroup.ChildrenCount - 1; - - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Vertical ? - (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Vertical ? - (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? - (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - - - _documentPaneDropTargetRightAsAnchorablePane.Visibility = - parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? - (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : - System.Windows.Visibility.Hidden; - } - else - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - } - } - else - { - _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; - } - } - else - { - areaElement = _gridDocumentPaneDropTargets; - var dropAreaDocumentPaneGroup = area as DropArea; - var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; - var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; - - if (parentDocumentPaneGroup != null && - parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) - { - var manager = parentDocumentPaneGroup.Root.Manager; - if (!manager.AllowMixedOrientation) - { - _documentPaneDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; - } - else - { - _documentPaneDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneDropTargetRight.Visibility = Visibility.Visible; - _documentPaneDropTargetTop.Visibility = Visibility.Visible; - _documentPaneDropTargetBottom.Visibility = Visibility.Visible; - } - - } - else if (parentDocumentPaneGroup == null && - layoutDocumentPane != null && - layoutDocumentPane.ChildrenCount == 0) - { - _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; - _documentPaneDropTargetRight.Visibility = Visibility.Hidden; - _documentPaneDropTargetTop.Visibility = Visibility.Hidden; - _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; - } - else - { - _documentPaneDropTargetLeft.Visibility = Visibility.Visible; - _documentPaneDropTargetRight.Visibility = Visibility.Visible; - _documentPaneDropTargetTop.Visibility = Visibility.Visible; - _documentPaneDropTargetBottom.Visibility = Visibility.Visible; - } - } - } - break; - } - - Canvas.SetLeft(areaElement, area.DetectionRect.Left - Left); - Canvas.SetTop(areaElement, area.DetectionRect.Top - Top); - areaElement.Width = area.DetectionRect.Width; - areaElement.Height = area.DetectionRect.Height; - areaElement.Visibility = System.Windows.Visibility.Visible; - } - - void IOverlayWindow.DragLeave(IDropArea area) - { - _visibleAreas.Remove(area); - - FrameworkElement areaElement; - switch (area.Type) - { - case DropAreaType.DockingManager: - areaElement = _gridDockingManagerDropTargets; - break; - case DropAreaType.AnchorablePane: - areaElement = _gridAnchorablePaneDropTargets; - break; - case DropAreaType.DocumentPaneGroup: - areaElement = _gridDocumentPaneDropTargets; - break; - case DropAreaType.DocumentPane: - default: - { - bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; - if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) - areaElement = _gridDocumentPaneFullDropTargets; - else - areaElement = _gridDocumentPaneDropTargets; - } - break; - } - - areaElement.Visibility = System.Windows.Visibility.Hidden; - } - - void IOverlayWindow.DragEnter(IDropTarget target) - { - var previewBoxPath = target.GetPreviewPath(this, _floatingWindow.Model as LayoutFloatingWindow); - if (previewBoxPath != null) - { - _previewBox.Data = previewBoxPath; - _previewBox.Visibility = System.Windows.Visibility.Visible; - } - } - - void IOverlayWindow.DragLeave(IDropTarget target) - { - _previewBox.Visibility = System.Windows.Visibility.Hidden; - } - - void IOverlayWindow.DragDrop(IDropTarget target) - { - target.Drop(_floatingWindow.Model as LayoutFloatingWindow); - } - - - } + public class OverlayWindow : Window, IOverlayWindow + { + static OverlayWindow() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(typeof(OverlayWindow))); + + OverlayWindow.AllowsTransparencyProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(true)); + OverlayWindow.WindowStyleProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(WindowStyle.None)); + OverlayWindow.ShowInTaskbarProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); + OverlayWindow.ShowActivatedProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(false)); + OverlayWindow.VisibilityProperty.OverrideMetadata(typeof(OverlayWindow), new FrameworkPropertyMetadata(Visibility.Hidden)); + } + + + internal OverlayWindow(IOverlayWindowHost host) + { + _host = host; + UpdateThemeResources(); + } + + + internal void UpdateThemeResources(Theme oldTheme = null) + { + if (Application.Current != null) + return; + + if (oldTheme != null) + { + var resourceDictionaryToRemove = + Resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); + if (resourceDictionaryToRemove != null) + Resources.MergedDictionaries.Remove( + resourceDictionaryToRemove); + } + + if (_host.Manager.Theme != null) + { + Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = _host.Manager.Theme.GetResourceUri() }); + } + } + + + Canvas _mainCanvasPanel; + Grid _gridDockingManagerDropTargets; + Grid _gridAnchorablePaneDropTargets; + Grid _gridDocumentPaneDropTargets; + Grid _gridDocumentPaneFullDropTargets; + + FrameworkElement _dockingManagerDropTargetBottom; + FrameworkElement _dockingManagerDropTargetTop; + FrameworkElement _dockingManagerDropTargetLeft; + FrameworkElement _dockingManagerDropTargetRight; + + FrameworkElement _anchorablePaneDropTargetBottom; + FrameworkElement _anchorablePaneDropTargetTop; + FrameworkElement _anchorablePaneDropTargetLeft; + FrameworkElement _anchorablePaneDropTargetRight; + FrameworkElement _anchorablePaneDropTargetInto; + + FrameworkElement _documentPaneDropTargetBottom; + FrameworkElement _documentPaneDropTargetTop; + FrameworkElement _documentPaneDropTargetLeft; + FrameworkElement _documentPaneDropTargetRight; + FrameworkElement _documentPaneDropTargetInto; + + FrameworkElement _documentPaneDropTargetBottomAsAnchorablePane; + FrameworkElement _documentPaneDropTargetTopAsAnchorablePane; + FrameworkElement _documentPaneDropTargetLeftAsAnchorablePane; + FrameworkElement _documentPaneDropTargetRightAsAnchorablePane; + + FrameworkElement _documentPaneFullDropTargetBottom; + FrameworkElement _documentPaneFullDropTargetTop; + FrameworkElement _documentPaneFullDropTargetLeft; + FrameworkElement _documentPaneFullDropTargetRight; + FrameworkElement _documentPaneFullDropTargetInto; + + Path _previewBox; + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + _mainCanvasPanel = GetTemplateChild("PART_DropTargetsContainer") as Canvas; + _gridDockingManagerDropTargets = GetTemplateChild("PART_DockingManagerDropTargets") as Grid; + _gridAnchorablePaneDropTargets = GetTemplateChild("PART_AnchorablePaneDropTargets") as Grid; + _gridDocumentPaneDropTargets = GetTemplateChild("PART_DocumentPaneDropTargets") as Grid; + _gridDocumentPaneFullDropTargets = GetTemplateChild("PART_DocumentPaneFullDropTargets") as Grid; + + _gridDockingManagerDropTargets.Visibility = System.Windows.Visibility.Hidden; + _gridAnchorablePaneDropTargets.Visibility = System.Windows.Visibility.Hidden; + _gridDocumentPaneDropTargets.Visibility = System.Windows.Visibility.Hidden; + if (_gridDocumentPaneFullDropTargets != null) + _gridDocumentPaneFullDropTargets.Visibility = System.Windows.Visibility.Hidden; + + _dockingManagerDropTargetBottom = GetTemplateChild("PART_DockingManagerDropTargetBottom") as FrameworkElement; + _dockingManagerDropTargetTop = GetTemplateChild("PART_DockingManagerDropTargetTop") as FrameworkElement; + _dockingManagerDropTargetLeft = GetTemplateChild("PART_DockingManagerDropTargetLeft") as FrameworkElement; + _dockingManagerDropTargetRight = GetTemplateChild("PART_DockingManagerDropTargetRight") as FrameworkElement; + + _anchorablePaneDropTargetBottom = GetTemplateChild("PART_AnchorablePaneDropTargetBottom") as FrameworkElement; + _anchorablePaneDropTargetTop = GetTemplateChild("PART_AnchorablePaneDropTargetTop") as FrameworkElement; + _anchorablePaneDropTargetLeft = GetTemplateChild("PART_AnchorablePaneDropTargetLeft") as FrameworkElement; + _anchorablePaneDropTargetRight = GetTemplateChild("PART_AnchorablePaneDropTargetRight") as FrameworkElement; + _anchorablePaneDropTargetInto = GetTemplateChild("PART_AnchorablePaneDropTargetInto") as FrameworkElement; + + _documentPaneDropTargetBottom = GetTemplateChild("PART_DocumentPaneDropTargetBottom") as FrameworkElement; + _documentPaneDropTargetTop = GetTemplateChild("PART_DocumentPaneDropTargetTop") as FrameworkElement; + _documentPaneDropTargetLeft = GetTemplateChild("PART_DocumentPaneDropTargetLeft") as FrameworkElement; + _documentPaneDropTargetRight = GetTemplateChild("PART_DocumentPaneDropTargetRight") as FrameworkElement; + _documentPaneDropTargetInto = GetTemplateChild("PART_DocumentPaneDropTargetInto") as FrameworkElement; + + _documentPaneDropTargetBottomAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetBottomAsAnchorablePane") as FrameworkElement; + _documentPaneDropTargetTopAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetTopAsAnchorablePane") as FrameworkElement; + _documentPaneDropTargetLeftAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetLeftAsAnchorablePane") as FrameworkElement; + _documentPaneDropTargetRightAsAnchorablePane = GetTemplateChild("PART_DocumentPaneDropTargetRightAsAnchorablePane") as FrameworkElement; + + _documentPaneFullDropTargetBottom = GetTemplateChild("PART_DocumentPaneFullDropTargetBottom") as FrameworkElement; + _documentPaneFullDropTargetTop = GetTemplateChild("PART_DocumentPaneFullDropTargetTop") as FrameworkElement; + _documentPaneFullDropTargetLeft = GetTemplateChild("PART_DocumentPaneFullDropTargetLeft") as FrameworkElement; + _documentPaneFullDropTargetRight = GetTemplateChild("PART_DocumentPaneFullDropTargetRight") as FrameworkElement; + _documentPaneFullDropTargetInto = GetTemplateChild("PART_DocumentPaneFullDropTargetInto") as FrameworkElement; + + _previewBox = GetTemplateChild("PART_PreviewBox") as Path; + } + + + internal void EnableDropTargets() + { + //Trace.WriteLine("EnableDropTargets()"); + if (_mainCanvasPanel != null) + _mainCanvasPanel.Visibility = System.Windows.Visibility.Visible; + } + + internal void HideDropTargets() + { + //Trace.WriteLine("HideDropTargets()"); + if (_mainCanvasPanel != null) + _mainCanvasPanel.Visibility = System.Windows.Visibility.Hidden; + + } + + IOverlayWindowHost _host; + + IEnumerable IOverlayWindow.GetTargets() + { + foreach (var visibleArea in _visibleAreas) + { + switch (visibleArea.Type) + { + case DropAreaType.DockingManager: + { + var dropAreaDockingManager = visibleArea as DropArea; + yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetLeft.GetScreenArea(), DropTargetType.DockingManagerDockLeft); + yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetTop.GetScreenArea(), DropTargetType.DockingManagerDockTop); + yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetBottom.GetScreenArea(), DropTargetType.DockingManagerDockBottom); + yield return new DockingManagerDropTarget(dropAreaDockingManager.AreaElement, _dockingManagerDropTargetRight.GetScreenArea(), DropTargetType.DockingManagerDockRight); + } + break; + case DropAreaType.AnchorablePane: + { + var dropAreaAnchorablePane = visibleArea as DropArea; + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetLeft.GetScreenArea(), DropTargetType.AnchorablePaneDockLeft); + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetTop.GetScreenArea(), DropTargetType.AnchorablePaneDockTop); + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetRight.GetScreenArea(), DropTargetType.AnchorablePaneDockRight); + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetBottom.GetScreenArea(), DropTargetType.AnchorablePaneDockBottom); + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, _anchorablePaneDropTargetInto.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); + + var parentPaneModel = dropAreaAnchorablePane.AreaElement.Model as LayoutAnchorablePane; + LayoutAnchorableTabItem lastAreaTabItem = null; + foreach (var dropAreaTabItem in dropAreaAnchorablePane.AreaElement.FindVisualChildren()) + { + var tabItemModel = dropAreaTabItem.Model as LayoutAnchorable; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.AnchorablePaneDockInside, tabIndex); + } + + if (lastAreaTabItem != null) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); + if (newAreaTabItemScreenArea.Right < dropAreaAnchorablePane.AreaElement.GetScreenArea().Right) + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, newAreaTabItemScreenArea, DropTargetType.AnchorablePaneDockInside, parentPaneModel.Children.Count); + } + + var dropAreaTitle = dropAreaAnchorablePane.AreaElement.FindVisualChildren().FirstOrDefault(); + if (dropAreaTitle != null) + yield return new AnchorablePaneDropTarget(dropAreaAnchorablePane.AreaElement, dropAreaTitle.GetScreenArea(), DropTargetType.AnchorablePaneDockInside); + } + break; + case DropAreaType.DocumentPane: + { + bool isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) + { + var dropAreaDocumentPane = visibleArea as DropArea; + if (_documentPaneFullDropTargetLeft.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); + if (_documentPaneFullDropTargetTop.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); + if (_documentPaneFullDropTargetRight.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); + if (_documentPaneFullDropTargetBottom.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); + if (_documentPaneFullDropTargetInto.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneFullDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); + + var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; + LayoutDocumentTabItem lastAreaTabItem = null; + foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) + { + var tabItemModel = dropAreaTabItem.Model; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); + } + + if (lastAreaTabItem != null) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); + if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); + } + + if (_documentPaneDropTargetLeftAsAnchorablePane.IsVisible) + yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeftAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableLeft); + if (_documentPaneDropTargetTopAsAnchorablePane.IsVisible) + yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTopAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableTop); + if (_documentPaneDropTargetRightAsAnchorablePane.IsVisible) + yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRightAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableRight); + if (_documentPaneDropTargetBottomAsAnchorablePane.IsVisible) + yield return new DocumentPaneDropAsAnchorableTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottomAsAnchorablePane.GetScreenArea(), DropTargetType.DocumentPaneDockAsAnchorableBottom); + } + else + { + + var dropAreaDocumentPane = visibleArea as DropArea; + if (_documentPaneDropTargetLeft.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetLeft.GetScreenArea(), DropTargetType.DocumentPaneDockLeft); + if (_documentPaneDropTargetTop.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetTop.GetScreenArea(), DropTargetType.DocumentPaneDockTop); + if (_documentPaneDropTargetRight.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetRight.GetScreenArea(), DropTargetType.DocumentPaneDockRight); + if (_documentPaneDropTargetBottom.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetBottom.GetScreenArea(), DropTargetType.DocumentPaneDockBottom); + if (_documentPaneDropTargetInto.IsVisible) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneDockInside); + + var parentPaneModel = dropAreaDocumentPane.AreaElement.Model as LayoutDocumentPane; + LayoutDocumentTabItem lastAreaTabItem = null; + foreach (var dropAreaTabItem in dropAreaDocumentPane.AreaElement.FindVisualChildren()) + { + var tabItemModel = dropAreaTabItem.Model; + lastAreaTabItem = lastAreaTabItem == null || lastAreaTabItem.GetScreenArea().Right < dropAreaTabItem.GetScreenArea().Right ? + dropAreaTabItem : lastAreaTabItem; + int tabIndex = parentPaneModel.Children.IndexOf(tabItemModel); + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, dropAreaTabItem.GetScreenArea(), DropTargetType.DocumentPaneDockInside, tabIndex); + } + + if (lastAreaTabItem != null) + { + var lastAreaTabItemScreenArea = lastAreaTabItem.GetScreenArea(); + var newAreaTabItemScreenArea = new Rect(lastAreaTabItemScreenArea.TopRight, new Point(lastAreaTabItemScreenArea.Right + lastAreaTabItemScreenArea.Width, lastAreaTabItemScreenArea.Bottom)); + if (newAreaTabItemScreenArea.Right < dropAreaDocumentPane.AreaElement.GetScreenArea().Right) + yield return new DocumentPaneDropTarget(dropAreaDocumentPane.AreaElement, newAreaTabItemScreenArea, DropTargetType.DocumentPaneDockInside, parentPaneModel.Children.Count); + } + } + } + break; + case DropAreaType.DocumentPaneGroup: + { + var dropAreaDocumentPane = visibleArea as DropArea; + if (_documentPaneDropTargetInto.IsVisible) + yield return new DocumentPaneGroupDropTarget(dropAreaDocumentPane.AreaElement, _documentPaneDropTargetInto.GetScreenArea(), DropTargetType.DocumentPaneGroupDockInside); + } + break; + } + + } + yield break; + } + + LayoutFloatingWindowControl _floatingWindow = null; + void IOverlayWindow.DragEnter(LayoutFloatingWindowControl floatingWindow) + { + _floatingWindow = floatingWindow; + EnableDropTargets(); + } + + void IOverlayWindow.DragLeave(LayoutFloatingWindowControl floatingWindow) + { + Visibility = System.Windows.Visibility.Hidden; + _floatingWindow = null; + } + + protected override void OnClosing(System.ComponentModel.CancelEventArgs e) + { + base.OnClosing(e); + } + + + List _visibleAreas = new List(); + void IOverlayWindow.DragEnter(IDropArea area) + { + _visibleAreas.Add(area); + + FrameworkElement areaElement; + switch (area.Type) + { + case DropAreaType.DockingManager: + areaElement = _gridDockingManagerDropTargets; + break; + case DropAreaType.AnchorablePane: + areaElement = _gridAnchorablePaneDropTargets; + break; + case DropAreaType.DocumentPaneGroup: + { + areaElement = _gridDocumentPaneDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = (dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPaneGroup).Children.First() as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; + + _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; + } + break; + case DropAreaType.DocumentPane: + default: + { + bool isDraggingAnchorables = false; + if (_floatingWindow != null) + isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + + if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) + { + areaElement = _gridDocumentPaneFullDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; + + if (parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) + { + var manager = parentDocumentPaneGroup.Root.Manager; + if (!manager.AllowMixedOrientation) + { + _documentPaneFullDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + _documentPaneFullDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + } + else + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; + _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; + } + } + else if (parentDocumentPaneGroup == null && + layoutDocumentPane != null && + layoutDocumentPane.ChildrenCount == 0) + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Hidden; + } + else + { + _documentPaneFullDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneFullDropTargetRight.Visibility = Visibility.Visible; + _documentPaneFullDropTargetTop.Visibility = Visibility.Visible; + _documentPaneFullDropTargetBottom.Visibility = Visibility.Visible; + } + + if (parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) + { + int indexOfDocumentPane = parentDocumentPaneGroup.Children.Where(ch => ch.IsVisible).ToList().IndexOf(layoutDocumentPane); + bool isFirstChild = indexOfDocumentPane == 0; + bool isLastChild = indexOfDocumentPane == parentDocumentPaneGroup.ChildrenCount - 1; + + var manager = parentDocumentPaneGroup.Root.Manager; + if (!manager.AllowMixedOrientation) + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Vertical ? + (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : + System.Windows.Visibility.Hidden; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Vertical ? + (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : + System.Windows.Visibility.Hidden; + + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? + (isFirstChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : + System.Windows.Visibility.Hidden; + + + _documentPaneDropTargetRightAsAnchorablePane.Visibility = + parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? + (isLastChild ? System.Windows.Visibility.Visible : System.Windows.Visibility.Hidden) : + System.Windows.Visibility.Hidden; + } + else + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + } + } + else + { + _documentPaneDropTargetBottomAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetLeftAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetRightAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + _documentPaneDropTargetTopAsAnchorablePane.Visibility = System.Windows.Visibility.Visible; + } + } + else + { + areaElement = _gridDocumentPaneDropTargets; + var dropAreaDocumentPaneGroup = area as DropArea; + var layoutDocumentPane = dropAreaDocumentPaneGroup.AreaElement.Model as LayoutDocumentPane; + var parentDocumentPaneGroup = layoutDocumentPane.Parent as LayoutDocumentPaneGroup; + + if (parentDocumentPaneGroup != null && + parentDocumentPaneGroup.Children.Where(c => c.IsVisible).Count() > 1) + { + var manager = parentDocumentPaneGroup.Root.Manager; + if (!manager.AllowMixedOrientation) + { + _documentPaneDropTargetLeft.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Horizontal ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = parentDocumentPaneGroup.Orientation == Orientation.Vertical ? Visibility.Visible : Visibility.Hidden; + } + else + { + _documentPaneDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneDropTargetRight.Visibility = Visibility.Visible; + _documentPaneDropTargetTop.Visibility = Visibility.Visible; + _documentPaneDropTargetBottom.Visibility = Visibility.Visible; + } + + } + else if (parentDocumentPaneGroup == null && + layoutDocumentPane != null && + layoutDocumentPane.ChildrenCount == 0) + { + _documentPaneDropTargetLeft.Visibility = Visibility.Hidden; + _documentPaneDropTargetRight.Visibility = Visibility.Hidden; + _documentPaneDropTargetTop.Visibility = Visibility.Hidden; + _documentPaneDropTargetBottom.Visibility = Visibility.Hidden; + } + else + { + _documentPaneDropTargetLeft.Visibility = Visibility.Visible; + _documentPaneDropTargetRight.Visibility = Visibility.Visible; + _documentPaneDropTargetTop.Visibility = Visibility.Visible; + _documentPaneDropTargetBottom.Visibility = Visibility.Visible; + } + } + } + break; + } + + if (areaElement != null) + { + Canvas.SetLeft(areaElement, area.DetectionRect.Left - Left); + Canvas.SetTop(areaElement, area.DetectionRect.Top - Top); + areaElement.Width = area.DetectionRect.Width; + areaElement.Height = area.DetectionRect.Height; + areaElement.Visibility = System.Windows.Visibility.Visible; + } + } + + void IOverlayWindow.DragLeave(IDropArea area) + { + _visibleAreas.Remove(area); + + FrameworkElement areaElement; + switch (area.Type) + { + case DropAreaType.DockingManager: + areaElement = _gridDockingManagerDropTargets; + break; + case DropAreaType.AnchorablePane: + areaElement = _gridAnchorablePaneDropTargets; + break; + case DropAreaType.DocumentPaneGroup: + areaElement = _gridDocumentPaneDropTargets; + break; + case DropAreaType.DocumentPane: + default: + { + bool isDraggingAnchorables = false; + if (_floatingWindow != null) + isDraggingAnchorables = _floatingWindow.Model is LayoutAnchorableFloatingWindow; + + if (isDraggingAnchorables && _gridDocumentPaneFullDropTargets != null) + areaElement = _gridDocumentPaneFullDropTargets; + else + areaElement = _gridDocumentPaneDropTargets; + } + break; + } + + if (areaElement != null) + areaElement.Visibility = System.Windows.Visibility.Hidden; + } + + void IOverlayWindow.DragEnter(IDropTarget target) + { + var previewBoxPath = target.GetPreviewPath(this, _floatingWindow.Model as LayoutFloatingWindow); + if (previewBoxPath != null) + { + _previewBox.Data = previewBoxPath; + _previewBox.Visibility = System.Windows.Visibility.Visible; + } + } + + void IOverlayWindow.DragLeave(IDropTarget target) + { + _previewBox.Visibility = System.Windows.Visibility.Hidden; + } + + void IOverlayWindow.DragDrop(IDropTarget target) + { + target.Drop(_floatingWindow.Model as LayoutFloatingWindow); + } + + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs index e05af984..7c2b845e 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/DockingManager.cs @@ -37,3174 +37,3203 @@ using Xceed.Wpf.AvalonDock.Themes; namespace Xceed.Wpf.AvalonDock { - [ContentProperty("Layout")] - [TemplatePart(Name="PART_AutoHideArea")] - public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer - { - static DockingManager() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(typeof(DockingManager))); - FocusableProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(false)); - HwndSource.DefaultAcquireHwndFocusInMenuMode = false; - } - - - public DockingManager() - { - Layout = new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) }; - - - this.Loaded += new RoutedEventHandler(DockingManager_Loaded); - this.Unloaded += new RoutedEventHandler(DockingManager_Unloaded); - } - - #region Layout - - /// - /// Layout Dependency Property - /// - public static readonly DependencyProperty LayoutProperty = - DependencyProperty.Register("Layout", typeof(LayoutRoot), typeof(DockingManager), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnLayoutChanged), - new CoerceValueCallback(CoerceLayoutValue))); - - /// - /// Gets or sets the Layout property. This dependency property - /// indicates layout tree. - /// - public LayoutRoot Layout - { - get { return (LayoutRoot)GetValue(LayoutProperty); } - set { SetValue(LayoutProperty, value); } - } - - /// - /// Handles changes to the Layout property. - /// - private static void OnLayoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutChanged(e.OldValue as LayoutRoot, e.NewValue as LayoutRoot); - } - - /// - /// Provides derived classes an opportunity to handle changes to the property. - /// - protected virtual void OnLayoutChanged(LayoutRoot oldLayout, LayoutRoot newLayout) - { - if (oldLayout != null) - { - oldLayout.PropertyChanged -= new PropertyChangedEventHandler(OnLayoutRootPropertyChanged); - oldLayout.Updated -= new EventHandler(OnLayoutRootUpdated); - } - - foreach (var fwc in _fwList.ToArray()) - { - fwc.KeepContentVisibleOnClose = true; - fwc.InternalClose(); - } - - _fwList.Clear(); - - DetachDocumentsSource(oldLayout, DocumentsSource); - DetachAnchorablesSource(oldLayout, AnchorablesSource); - - if (oldLayout != null && - oldLayout.Manager == this) - oldLayout.Manager = null; - - ClearLogicalChildrenList(); - DetachLayoutItems(); - - Layout.Manager = this; - - AttachLayoutItems(); - AttachDocumentsSource(newLayout, DocumentsSource); - AttachAnchorablesSource(newLayout, AnchorablesSource); - - if (IsLoaded) - { - LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; - LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl; - TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl; - RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl; - BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl; - - foreach (var fw in Layout.FloatingWindows.ToArray()) - { - if (fw.IsValid) - _fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl); - } - - foreach (var fw in _fwList) - { - //fw.Owner = Window.GetWindow(this); - //fw.SetParentToMainWindowOf(this); - } - } - - - if (newLayout != null) - { - newLayout.PropertyChanged += new PropertyChangedEventHandler(OnLayoutRootPropertyChanged); - newLayout.Updated += new EventHandler(OnLayoutRootUpdated); - } - - if (LayoutChanged != null) - LayoutChanged(this, EventArgs.Empty); - - //if (Layout != null) - // Layout.CollectGarbage(); - - CommandManager.InvalidateRequerySuggested(); - } - - DispatcherOperation _setFocusAsyncOperation = null; - - void OnLayoutRootPropertyChanged(object sender, PropertyChangedEventArgs e) - { - if (e.PropertyName == "RootPanel") - { - if (IsInitialized) - { - var layoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; - LayoutRootPanel = layoutRootPanel; - } - } - else if (e.PropertyName == "ActiveContent") - { - if (Layout.ActiveContent != null) - { - //Debug.WriteLine(new StackTrace().ToString()); - - //set focus on active element only after a layout pass is completed - //it's possible that it is not yet visible in the visual tree - if (_setFocusAsyncOperation == null) - { - _setFocusAsyncOperation = Dispatcher.BeginInvoke(new Action(() => - { - if (Layout.ActiveContent != null) - FocusElementManager.SetFocusOnLastElement(Layout.ActiveContent); - _setFocusAsyncOperation = null; - }), DispatcherPriority.Background); - } - } - - if (!_insideInternalSetActiveContent) - ActiveContent = Layout.ActiveContent != null ? - Layout.ActiveContent.Content : null; - } - } - - void OnLayoutRootUpdated(object sender, EventArgs e) - { - CommandManager.InvalidateRequerySuggested(); - } - - - /// - /// Event fired when property changes - /// - public event EventHandler LayoutChanged; - - /// - /// Coerces the value. - /// - private static object CoerceLayoutValue(DependencyObject d, object value) - { - if (value == null) - return new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) }; - - ((DockingManager)d).OnLayoutChanging(value as LayoutRoot); - - return value; - } - - /// - /// Event fired when property is about to be changed - /// - public event EventHandler LayoutChanging; - - void OnLayoutChanging(LayoutRoot newLayout) - { - if (LayoutChanging != null) - LayoutChanging(this, EventArgs.Empty); - } - - - #region LayoutUpdateStrategy - - /// - /// LayoutUpdateStrategy Dependency Property - /// - public static readonly DependencyProperty LayoutUpdateStrategyProperty = - DependencyProperty.Register("LayoutUpdateStrategy", typeof(ILayoutUpdateStrategy), typeof(DockingManager), - new FrameworkPropertyMetadata((ILayoutUpdateStrategy)null)); - - /// - /// Gets or sets the LayoutUpdateStrategy property. This dependency property - /// indicates the strategy class to call when AvalonDock needs to positionate a LayoutAnchorable inside an existing layout. - /// - /// Sometimes it's impossible to automatically insert an anchorable in the layout without specifing the target parent pane. - /// Set this property to an object that will be asked to insert the anchorable to the desidered position. - public ILayoutUpdateStrategy LayoutUpdateStrategy - { - get { return (ILayoutUpdateStrategy)GetValue(LayoutUpdateStrategyProperty); } - set { SetValue(LayoutUpdateStrategyProperty, value); } - } - - #endregion - - - - #endregion - - public override void OnApplyTemplate() - { - base.OnApplyTemplate(); - - SetupAutoHideWindow(); - } - - protected override void OnInitialized(EventArgs e) - { - base.OnInitialized(e); - - if (Layout.Manager == this) - { - LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; - LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl; - TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl; - RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl; - BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl; - } - - - } - - void DockingManager_Loaded(object sender, RoutedEventArgs e) - { - if (!DesignerProperties.GetIsInDesignMode(this)) - { - //load windows not already loaded! - foreach (var fw in Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw))) - _fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl); - - //create the overlaywindow if it's possible - if (IsVisible) - CreateOverlayWindow(); - FocusElementManager.SetupFocusManagement(this); - } - } - - void DockingManager_Unloaded(object sender, RoutedEventArgs e) - { - - if (!DesignerProperties.GetIsInDesignMode(this)) - { - _autoHideWindowManager.HideAutoWindow(); - - foreach (var fw in _fwList.ToArray()) - { - //fw.Owner = null; - fw.SetParentWindowToNull(); - fw.KeepContentVisibleOnClose = true; - fw.Close(); - } - - DestroyOverlayWindow(); - FocusElementManager.FinalizeFocusManagement(this); - } - } - - internal UIElement CreateUIElementForModel(ILayoutElement model) - { - if (model is LayoutPanel) - return new LayoutPanelControl(model as LayoutPanel); - if (model is LayoutAnchorablePaneGroup) - return new LayoutAnchorablePaneGroupControl(model as LayoutAnchorablePaneGroup); - if (model is LayoutDocumentPaneGroup) - return new LayoutDocumentPaneGroupControl(model as LayoutDocumentPaneGroup); - - if (model is LayoutAnchorSide) - { - var templateModelView = new LayoutAnchorSideControl(model as LayoutAnchorSide); - templateModelView.SetBinding(LayoutAnchorSideControl.TemplateProperty, new Binding("AnchorSideTemplate") { Source = this }); - return templateModelView; - } - if (model is LayoutAnchorGroup) - { - var templateModelView = new LayoutAnchorGroupControl(model as LayoutAnchorGroup); - templateModelView.SetBinding(LayoutAnchorGroupControl.TemplateProperty, new Binding("AnchorGroupTemplate") { Source = this }); - return templateModelView; - } - - if (model is LayoutDocumentPane) - { - var templateModelView = new LayoutDocumentPaneControl(model as LayoutDocumentPane); - templateModelView.SetBinding(LayoutDocumentPaneControl.StyleProperty, new Binding("DocumentPaneControlStyle") { Source = this }); - return templateModelView; - } - if (model is LayoutAnchorablePane) - { - var templateModelView = new LayoutAnchorablePaneControl(model as LayoutAnchorablePane); - templateModelView.SetBinding(LayoutAnchorablePaneControl.StyleProperty, new Binding("AnchorablePaneControlStyle") { Source = this }); - return templateModelView; - } - - if (model is LayoutAnchorableFloatingWindow) - { - if (DesignerProperties.GetIsInDesignMode(this)) - return null; - var modelFW = model as LayoutAnchorableFloatingWindow; - var newFW = new LayoutAnchorableFloatingWindowControl(modelFW) - { - //Owner = Window.GetWindow(this) - }; - newFW.SetParentToMainWindowOf(this); - - var paneForExtensions = modelFW.RootPanel.Children.OfType().FirstOrDefault(); - if (paneForExtensions != null) - { - //ensure that floating window position is inside current (or nearest) monitor - paneForExtensions.KeepInsideNearestMonitor(); - - newFW.Left = paneForExtensions.FloatingLeft; - newFW.Top = paneForExtensions.FloatingTop; - newFW.Width = paneForExtensions.FloatingWidth; - newFW.Height = paneForExtensions.FloatingHeight; - } - - newFW.ShowInTaskbar = false; - newFW.Show(); - return newFW; - } - - if (model is LayoutDocumentFloatingWindow) - { - if (DesignerProperties.GetIsInDesignMode(this)) - return null; - var modelFW = model as LayoutDocumentFloatingWindow; - var newFW = new LayoutDocumentFloatingWindowControl(modelFW) - { - //Owner = Window.GetWindow(this) - }; - newFW.SetParentToMainWindowOf(this); - - var paneForExtensions = modelFW.RootDocument; - if (paneForExtensions != null) - { - //ensure that floating window position is inside current (or nearest) monitor - paneForExtensions.KeepInsideNearestMonitor(); - - newFW.Left = paneForExtensions.FloatingLeft; - newFW.Top = paneForExtensions.FloatingTop; - newFW.Width = paneForExtensions.FloatingWidth; - newFW.Height = paneForExtensions.FloatingHeight; - } - - newFW.ShowInTaskbar = false; - newFW.Show(); - return newFW; - } - - if (model is LayoutDocument) - { - var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument }; - return templateModelView; - } - - return null; - } - - - - #region DocumentPaneTemplate - - /// - /// DocumentPaneTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentPaneTemplateProperty = - DependencyProperty.Register("DocumentPaneTemplate", typeof(ControlTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((ControlTemplate)null, - new PropertyChangedCallback(OnDocumentPaneTemplateChanged))); - - /// - /// Gets or sets the DocumentPaneDataTemplate property. This dependency property - /// indicates . - /// - public ControlTemplate DocumentPaneTemplate - { - get { return (ControlTemplate)GetValue(DocumentPaneTemplateProperty); } - set { SetValue(DocumentPaneTemplateProperty, value); } - } - - /// - /// Handles changes to the DocumentPaneTemplate property. - /// - private static void OnDocumentPaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentPaneTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneTemplate property. - /// - protected virtual void OnDocumentPaneTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - #region AnchorablePaneTemplate - - /// - /// AnchorablePaneTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorablePaneTemplateProperty = - DependencyProperty.Register("AnchorablePaneTemplate", typeof(ControlTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((ControlTemplate)null, - new PropertyChangedCallback(OnAnchorablePaneTemplateChanged))); - - /// - /// Gets or sets the AnchorablePaneTemplate property. This dependency property - /// indicates .... - /// - public ControlTemplate AnchorablePaneTemplate - { - get { return (ControlTemplate)GetValue(AnchorablePaneTemplateProperty); } - set { SetValue(AnchorablePaneTemplateProperty, value); } - } - - /// - /// Handles changes to the AnchorablePaneDataTemplate property. - /// - private static void OnAnchorablePaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorablePaneTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorablePaneDataTemplate property. - /// - protected virtual void OnAnchorablePaneTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - #region AnchorSideTemplate - - /// - /// AnchorSideTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorSideTemplateProperty = - DependencyProperty.Register("AnchorSideTemplate", typeof(ControlTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((ControlTemplate)null)); - - /// - /// Gets or sets the AnchorSideTemplate property. This dependency property - /// indicates .... - /// - public ControlTemplate AnchorSideTemplate - { - get { return (ControlTemplate)GetValue(AnchorSideTemplateProperty); } - set { SetValue(AnchorSideTemplateProperty, value); } - } - - #endregion - - #region AnchorGroupTemplate - - /// - /// AnchorGroupTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorGroupTemplateProperty = - DependencyProperty.Register("AnchorGroupTemplate", typeof(ControlTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((ControlTemplate)null)); - - /// - /// Gets or sets the AnchorGroupTemplate property. This dependency property - /// indicates the template used to render the AnchorGroup control. - /// - public ControlTemplate AnchorGroupTemplate - { - get { return (ControlTemplate)GetValue(AnchorGroupTemplateProperty); } - set { SetValue(AnchorGroupTemplateProperty, value); } - } - - #endregion - - #region AnchorTemplate - - /// - /// AnchorTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorTemplateProperty = - DependencyProperty.Register("AnchorTemplate", typeof(ControlTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((ControlTemplate)null)); - - /// - /// Gets or sets the AnchorTemplate property. This dependency property - /// indicates .... - /// - public ControlTemplate AnchorTemplate - { - get { return (ControlTemplate)GetValue(AnchorTemplateProperty); } - set { SetValue(AnchorTemplateProperty, value); } - } - - #endregion - - #region DocumentPaneControlStyle - - /// - /// DocumentPaneControlStyle Dependency Property - /// - public static readonly DependencyProperty DocumentPaneControlStyleProperty = - DependencyProperty.Register("DocumentPaneControlStyle", typeof(Style), typeof(DockingManager), - new FrameworkPropertyMetadata((Style)null, - new PropertyChangedCallback(OnDocumentPaneControlStyleChanged))); - - /// - /// Gets or sets the DocumentPaneControlStyle property. This dependency property - /// indicates .... - /// - public Style DocumentPaneControlStyle - { - get { return (Style)GetValue(DocumentPaneControlStyleProperty); } - set { SetValue(DocumentPaneControlStyleProperty, value); } - } - - /// - /// Handles changes to the DocumentPaneControlStyle property. - /// - private static void OnDocumentPaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentPaneControlStyleChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneControlStyle property. - /// - protected virtual void OnDocumentPaneControlStyleChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - #region AnchorablePaneControlStyle - - /// - /// AnchorablePaneControlStyle Dependency Property - /// - public static readonly DependencyProperty AnchorablePaneControlStyleProperty = - DependencyProperty.Register("AnchorablePaneControlStyle", typeof(Style), typeof(DockingManager), - new FrameworkPropertyMetadata((Style)null, - new PropertyChangedCallback(OnAnchorablePaneControlStyleChanged))); - - /// - /// Gets or sets the AnchorablePaneControlStyle property. This dependency property - /// indicates the style to apply to AnchorablePaneControl. - /// - public Style AnchorablePaneControlStyle - { - get { return (Style)GetValue(AnchorablePaneControlStyleProperty); } - set { SetValue(AnchorablePaneControlStyleProperty, value); } - } - - /// - /// Handles changes to the AnchorablePaneControlStyle property. - /// - private static void OnAnchorablePaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorablePaneControlStyleChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorablePaneControlStyle property. - /// - protected virtual void OnAnchorablePaneControlStyleChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - #region DocumentHeaderTemplate - - /// - /// DocumentHeaderTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentHeaderTemplateProperty = - DependencyProperty.Register("DocumentHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnDocumentHeaderTemplateChanged), - new CoerceValueCallback(CoerceDocumentHeaderTemplateValue))); - - /// - /// Gets or sets the DocumentHeaderTemplate property. This dependency property - /// indicates data template to use for document header. - /// - public DataTemplate DocumentHeaderTemplate - { - get { return (DataTemplate)GetValue(DocumentHeaderTemplateProperty); } - set { SetValue(DocumentHeaderTemplateProperty, value); } - } - - /// - /// Handles changes to the DocumentHeaderTemplate property. - /// - private static void OnDocumentHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentHeaderTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplate property. - /// - protected virtual void OnDocumentHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - /// - /// Coerces the DocumentHeaderTemplate value. - /// - private static object CoerceDocumentHeaderTemplateValue(DependencyObject d, object value) - { - if (value != null && - d.GetValue(DocumentHeaderTemplateSelectorProperty) != null) - return null; - return value; - } - - #endregion - - #region DocumentHeaderTemplateSelector - - /// - /// DocumentHeaderTemplateSelector Dependency Property - /// - public static readonly DependencyProperty DocumentHeaderTemplateSelectorProperty = - DependencyProperty.Register("DocumentHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnDocumentHeaderTemplateSelectorChanged), - new CoerceValueCallback(CoerceDocumentHeaderTemplateSelectorValue))); - - /// - /// Gets or sets the DocumentHeaderTemplateSelector property. This dependency property - /// indicates the template selector that is used when selcting the data template for the header. - /// - public DataTemplateSelector DocumentHeaderTemplateSelector - { - get { return (DataTemplateSelector)GetValue(DocumentHeaderTemplateSelectorProperty); } - set { SetValue(DocumentHeaderTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the DocumentHeaderTemplateSelector property. - /// - private static void OnDocumentHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentHeaderTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplateSelector property. - /// - protected virtual void OnDocumentHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null && - DocumentHeaderTemplate != null) - DocumentHeaderTemplate = null; - - if (DocumentPaneMenuItemHeaderTemplateSelector == null) - DocumentPaneMenuItemHeaderTemplateSelector = DocumentHeaderTemplateSelector; - - } - - /// - /// Coerces the DocumentHeaderTemplateSelector value. - /// - private static object CoerceDocumentHeaderTemplateSelectorValue(DependencyObject d, object value) - { - return value; - } - - #endregion - - #region DocumentTitleTemplate - - /// - /// DocumentTitleTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentTitleTemplateProperty = - DependencyProperty.Register("DocumentTitleTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnDocumentTitleTemplateChanged), - new CoerceValueCallback(CoerceDocumentTitleTemplateValue))); - - /// - /// Gets or sets the DocumentTitleTemplate property. This dependency property - /// indicates the datatemplate to use when creating the title for a document. - /// - public DataTemplate DocumentTitleTemplate - { - get { return (DataTemplate)GetValue(DocumentTitleTemplateProperty); } - set { SetValue(DocumentTitleTemplateProperty, value); } - } - - /// - /// Handles changes to the DocumentTitleTemplate property. - /// - private static void OnDocumentTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentTitleTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplate property. - /// - protected virtual void OnDocumentTitleTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - /// - /// Coerces the DocumentTitleTemplate value. - /// - private static object CoerceDocumentTitleTemplateValue(DependencyObject d, object value) - { - if (value != null && - d.GetValue(DocumentTitleTemplateSelectorProperty) != null) - return null; - - return value; - } - - #endregion - - #region DocumentTitleTemplateSelector - - /// - /// DocumentTitleTemplateSelector Dependency Property - /// - public static readonly DependencyProperty DocumentTitleTemplateSelectorProperty = - DependencyProperty.Register("DocumentTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnDocumentTitleTemplateSelectorChanged), - new CoerceValueCallback(CoerceDocumentTitleTemplateSelectorValue))); - - /// - /// Gets or sets the DocumentTitleTemplateSelector property. This dependency property - /// indicates the data template selector to use when creating the data template for the title. - /// - public DataTemplateSelector DocumentTitleTemplateSelector - { - get { return (DataTemplateSelector)GetValue(DocumentTitleTemplateSelectorProperty); } - set { SetValue(DocumentTitleTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the DocumentTitleTemplateSelector property. - /// - private static void OnDocumentTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentTitleTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplateSelector property. - /// - protected virtual void OnDocumentTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null) - DocumentTitleTemplate = null; - } - - /// - /// Coerces the DocumentTitleTemplateSelector value. - /// - private static object CoerceDocumentTitleTemplateSelectorValue(DependencyObject d, object value) - { - return value; - } - - #endregion - - #region AnchorableTitleTemplate - - /// - /// AnchorableTitleTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorableTitleTemplateProperty = - DependencyProperty.Register("AnchorableTitleTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnAnchorableTitleTemplateChanged), - new CoerceValueCallback(CoerceAnchorableTitleTemplateValue))); - - /// - /// Gets or sets the AnchorableTitleTemplate property. This dependency property - /// indicates the data template to use for anchorables title. - /// - public DataTemplate AnchorableTitleTemplate - { - get { return (DataTemplate)GetValue(AnchorableTitleTemplateProperty); } - set { SetValue(AnchorableTitleTemplateProperty, value); } - } - - /// - /// Handles changes to the AnchorableTitleTemplate property. - /// - private static void OnAnchorableTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorableTitleTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplate property. - /// - protected virtual void OnAnchorableTitleTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - /// - /// Coerces the AnchorableTitleTemplate value. - /// - private static object CoerceAnchorableTitleTemplateValue(DependencyObject d, object value) - { - if (value != null && - d.GetValue(AnchorableTitleTemplateSelectorProperty) != null) - return null; - return value; - } - - #endregion - - #region AnchorableTitleTemplateSelector - - /// - /// AnchorableTitleTemplateSelector Dependency Property - /// - public static readonly DependencyProperty AnchorableTitleTemplateSelectorProperty = - DependencyProperty.Register("AnchorableTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnAnchorableTitleTemplateSelectorChanged))); - - /// - /// Gets or sets the AnchorableTitleTemplateSelector property. This dependency property - /// indicates selctor to use when selecting data template for the title of anchorables. - /// - public DataTemplateSelector AnchorableTitleTemplateSelector - { - get { return (DataTemplateSelector)GetValue(AnchorableTitleTemplateSelectorProperty); } - set { SetValue(AnchorableTitleTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the AnchorableTitleTemplateSelector property. - /// - private static void OnAnchorableTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorableTitleTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplateSelector property. - /// - protected virtual void OnAnchorableTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null && - AnchorableTitleTemplate != null) - AnchorableTitleTemplate = null; - } - - #endregion - - #region AnchorableHeaderTemplate - - /// - /// AnchorableHeaderTemplate Dependency Property - /// - public static readonly DependencyProperty AnchorableHeaderTemplateProperty = - DependencyProperty.Register("AnchorableHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnAnchorableHeaderTemplateChanged), - new CoerceValueCallback(CoerceAnchorableHeaderTemplateValue))); - - /// - /// Gets or sets the AnchorableHeaderTemplate property. This dependency property - /// indicates the data template to use for anchorable templates. - /// - public DataTemplate AnchorableHeaderTemplate - { - get { return (DataTemplate)GetValue(AnchorableHeaderTemplateProperty); } - set { SetValue(AnchorableHeaderTemplateProperty, value); } - } - - /// - /// Handles changes to the AnchorableHeaderTemplate property. - /// - private static void OnAnchorableHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorableHeaderTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplate property. - /// - protected virtual void OnAnchorableHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - /// - /// Coerces the AnchorableHeaderTemplate value. - /// - private static object CoerceAnchorableHeaderTemplateValue(DependencyObject d, object value) - { - if (value != null && - d.GetValue(AnchorableHeaderTemplateSelectorProperty) != null) - return null; - - return value; - } - - #endregion - - #region AnchorableHeaderTemplateSelector - - /// - /// AnchorableHeaderTemplateSelector Dependency Property - /// - public static readonly DependencyProperty AnchorableHeaderTemplateSelectorProperty = - DependencyProperty.Register("AnchorableHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnAnchorableHeaderTemplateSelectorChanged))); - - /// - /// Gets or sets the AnchorableHeaderTemplateSelector property. This dependency property - /// indicates the selector to use when selecting the data template for anchorable headers. - /// - public DataTemplateSelector AnchorableHeaderTemplateSelector - { - get { return (DataTemplateSelector)GetValue(AnchorableHeaderTemplateSelectorProperty); } - set { SetValue(AnchorableHeaderTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the AnchorableHeaderTemplateSelector property. - /// - private static void OnAnchorableHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorableHeaderTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplateSelector property. - /// - protected virtual void OnAnchorableHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null) - AnchorableHeaderTemplate = null; - } - - #endregion - - protected override void OnGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) - { - //if (e.NewFocus is Grid) - // Trace.WriteLine(string.Format("DockingManager.OnGotKeyboardFocus({0})", e.NewFocus)); - base.OnGotKeyboardFocus(e); - } - - protected override void OnPreviewGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) - { - Trace.WriteLine( string.Format( "DockingManager.OnPreviewGotKeyboardFocus({0})", e.NewFocus ) ); - - base.OnPreviewGotKeyboardFocus(e); - } - - protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) - { - Trace.WriteLine( string.Format( "DockingManager.OnPreviewLostKeyboardFocus({0})", e.OldFocus ) ); - base.OnPreviewLostKeyboardFocus(e); - } - - protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) - { - Trace.WriteLine( string.Format( "DockingManager.OnMouseLeftButtonDown([{0}])", e.GetPosition( this ) ) ); - base.OnMouseLeftButtonDown(e); - } - - protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) - { - //Trace.WriteLine(string.Format("DockingManager.OnMouseMove([{0}])", e.GetPosition(this))); - base.OnMouseMove(e); - } - - - - #region LayoutRootPanel - - /// - /// LayoutRootPanel Dependency Property - /// - public static readonly DependencyProperty LayoutRootPanelProperty = - DependencyProperty.Register("LayoutRootPanel", typeof(LayoutPanelControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutPanelControl)null, - new PropertyChangedCallback(OnLayoutRootPanelChanged))); - - /// - /// Gets or sets the LayoutRootPanel property. This dependency property - /// indicates the layout panel control which is attached to the Layout.Root property. - /// - public LayoutPanelControl LayoutRootPanel - { - get { return (LayoutPanelControl)GetValue(LayoutRootPanelProperty); } - set { SetValue(LayoutRootPanelProperty, value); } - } - - /// - /// Handles changes to the LayoutRootPanel property. - /// - private static void OnLayoutRootPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutRootPanelChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LayoutRootPanel property. - /// - protected virtual void OnLayoutRootPanelChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - } - - #endregion - - #region RightSidePanel - - /// - /// RightSidePanel Dependency Property - /// - public static readonly DependencyProperty RightSidePanelProperty = - DependencyProperty.Register("RightSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, - new PropertyChangedCallback(OnRightSidePanelChanged))); - - /// - /// Gets or sets the RightSidePanel property. This dependency property - /// indicates right side anchor panel. - /// - public LayoutAnchorSideControl RightSidePanel - { - get { return (LayoutAnchorSideControl)GetValue(RightSidePanelProperty); } - set { SetValue(RightSidePanelProperty, value); } - } - - /// - /// Handles changes to the RightSidePanel property. - /// - private static void OnRightSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnRightSidePanelChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the RightSidePanel property. - /// - protected virtual void OnRightSidePanelChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - } - - #endregion - - #region LeftSidePanel - - /// - /// LeftSidePanel Dependency Property - /// - public static readonly DependencyProperty LeftSidePanelProperty = - DependencyProperty.Register("LeftSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, - new PropertyChangedCallback(OnLeftSidePanelChanged))); - - /// - /// Gets or sets the LeftSidePanel property. This dependency property - /// indicates the left side panel control. - /// - public LayoutAnchorSideControl LeftSidePanel - { - get { return (LayoutAnchorSideControl)GetValue(LeftSidePanelProperty); } - set { SetValue(LeftSidePanelProperty, value); } - } - - /// - /// Handles changes to the LeftSidePanel property. - /// - private static void OnLeftSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLeftSidePanelChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LeftSidePanel property. - /// - protected virtual void OnLeftSidePanelChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - } - - #endregion - - #region TopSidePanel - - /// - /// TopSidePanel Dependency Property - /// - public static readonly DependencyProperty TopSidePanelProperty = - DependencyProperty.Register("TopSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, - new PropertyChangedCallback(OnTopSidePanelChanged))); - - /// - /// Gets or sets the TopSidePanel property. This dependency property - /// indicates top side control panel. - /// - public LayoutAnchorSideControl TopSidePanel - { - get { return (LayoutAnchorSideControl)GetValue(TopSidePanelProperty); } - set { SetValue(TopSidePanelProperty, value); } - } - - /// - /// Handles changes to the TopSidePanel property. - /// - private static void OnTopSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnTopSidePanelChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the TopSidePanel property. - /// - protected virtual void OnTopSidePanelChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - } - - #endregion - - #region BottomSidePanel - - /// - /// BottomSidePanel Dependency Property - /// - public static readonly DependencyProperty BottomSidePanelProperty = - DependencyProperty.Register("BottomSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, - new PropertyChangedCallback(OnBottomSidePanelChanged))); - - /// - /// Gets or sets the BottomSidePanel property. This dependency property - /// indicates bottom side panel control. - /// - public LayoutAnchorSideControl BottomSidePanel - { - get { return (LayoutAnchorSideControl)GetValue(BottomSidePanelProperty); } - set { SetValue(BottomSidePanelProperty, value); } - } - - /// - /// Handles changes to the BottomSidePanel property. - /// - private static void OnBottomSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnBottomSidePanelChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the BottomSidePanel property. - /// - protected virtual void OnBottomSidePanelChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - } - - #endregion - - - #region LogicalChildren - - List _logicalChildren = new List(); - - protected override System.Collections.IEnumerator LogicalChildren - { - get - { - return _logicalChildren.Select(ch => ch.GetValueOrDefault()).GetEnumerator(); - } - } - - - internal void InternalAddLogicalChild(object element) - { - //System.Diagnostics.Trace.WriteLine("[{0}]InternalAddLogicalChild({1})", this, element); + [ContentProperty("Layout")] + [TemplatePart(Name="PART_AutoHideArea")] + public class DockingManager : Control, IOverlayWindowHost//, ILogicalChildrenContainer + { + static DockingManager() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(typeof(DockingManager))); + FocusableProperty.OverrideMetadata(typeof(DockingManager), new FrameworkPropertyMetadata(false)); + HwndSource.DefaultAcquireHwndFocusInMenuMode = false; + } + + + public DockingManager() + { + Layout = new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) }; + + + this.Loaded += new RoutedEventHandler(DockingManager_Loaded); + this.Unloaded += new RoutedEventHandler(DockingManager_Unloaded); + } + + #region Layout + + /// + /// Layout Dependency Property + /// + public static readonly DependencyProperty LayoutProperty = + DependencyProperty.Register("Layout", typeof(LayoutRoot), typeof(DockingManager), + new FrameworkPropertyMetadata(null, + new PropertyChangedCallback(OnLayoutChanged), + new CoerceValueCallback(CoerceLayoutValue))); + + /// + /// Gets or sets the Layout property. This dependency property + /// indicates layout tree. + /// + public LayoutRoot Layout + { + get { return (LayoutRoot)GetValue(LayoutProperty); } + set { SetValue(LayoutProperty, value); } + } + + /// + /// Handles changes to the Layout property. + /// + private static void OnLayoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutChanged(e.OldValue as LayoutRoot, e.NewValue as LayoutRoot); + } + + /// + /// Provides derived classes an opportunity to handle changes to the property. + /// + protected virtual void OnLayoutChanged(LayoutRoot oldLayout, LayoutRoot newLayout) + { + if (oldLayout != null) + { + oldLayout.PropertyChanged -= new PropertyChangedEventHandler(OnLayoutRootPropertyChanged); + oldLayout.Updated -= new EventHandler(OnLayoutRootUpdated); + } + + foreach (var fwc in _fwList.ToArray()) + { + fwc.KeepContentVisibleOnClose = true; + fwc.InternalClose(); + } + + _fwList.Clear(); + + DetachDocumentsSource(oldLayout, DocumentsSource); + DetachAnchorablesSource(oldLayout, AnchorablesSource); + + if (oldLayout != null && + oldLayout.Manager == this) + oldLayout.Manager = null; + + ClearLogicalChildrenList(); + DetachLayoutItems(); + + this.ActiveContent = null; + Layout.Manager = this; + + AttachLayoutItems(); + AttachDocumentsSource(newLayout, DocumentsSource); + AttachAnchorablesSource(newLayout, AnchorablesSource); + + if (IsLoaded) + { + LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; + LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl; + TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl; + RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl; + BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl; + + foreach (var fw in Layout.FloatingWindows.ToArray()) + { + if (fw.IsValid) + _fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl); + } + + foreach (var fw in _fwList) + { + //fw.Owner = Window.GetWindow(this); + //fw.SetParentToMainWindowOf(this); + } + } + + + if (newLayout != null) + { + newLayout.PropertyChanged += new PropertyChangedEventHandler(OnLayoutRootPropertyChanged); + newLayout.Updated += new EventHandler(OnLayoutRootUpdated); + } + + if (LayoutChanged != null) + LayoutChanged(this, EventArgs.Empty); + + //if (Layout != null) + // Layout.CollectGarbage(); + + CommandManager.InvalidateRequerySuggested(); + } + + DispatcherOperation _setFocusAsyncOperation = null; + + void OnLayoutRootPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == "RootPanel") + { + if (IsInitialized) + { + var layoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; + LayoutRootPanel = layoutRootPanel; + } + } + else if (e.PropertyName == "ActiveContent") + { + if (Layout.ActiveContent != null) + { + //Debug.WriteLine(new StackTrace().ToString()); + + //set focus on active element only after a layout pass is completed + //it's possible that it is not yet visible in the visual tree + if (_setFocusAsyncOperation == null) + { + _setFocusAsyncOperation = Dispatcher.BeginInvoke(new Action(() => + { + if (Layout.ActiveContent != null) + FocusElementManager.SetFocusOnLastElement(Layout.ActiveContent); + _setFocusAsyncOperation = null; + }), DispatcherPriority.Background); + } + } + + if (!_insideInternalSetActiveContent) + ActiveContent = Layout.ActiveContent != null ? + Layout.ActiveContent.Content : null; + } + } + + void OnLayoutRootUpdated(object sender, EventArgs e) + { + CommandManager.InvalidateRequerySuggested(); + } + + + /// + /// Event fired when property changes + /// + public event EventHandler LayoutChanged; + + /// + /// Coerces the value. + /// + private static object CoerceLayoutValue(DependencyObject d, object value) + { + if (value == null) + return new LayoutRoot() { RootPanel = new LayoutPanel(new LayoutDocumentPaneGroup(new LayoutDocumentPane())) }; + + ((DockingManager)d).OnLayoutChanging(value as LayoutRoot); + + return value; + } + + /// + /// Event fired when property is about to be changed + /// + public event EventHandler LayoutChanging; + + void OnLayoutChanging(LayoutRoot newLayout) + { + if (LayoutChanging != null) + LayoutChanging(this, EventArgs.Empty); + } + + + #region LayoutUpdateStrategy + + /// + /// LayoutUpdateStrategy Dependency Property + /// + public static readonly DependencyProperty LayoutUpdateStrategyProperty = + DependencyProperty.Register("LayoutUpdateStrategy", typeof(ILayoutUpdateStrategy), typeof(DockingManager), + new FrameworkPropertyMetadata((ILayoutUpdateStrategy)null)); + + /// + /// Gets or sets the LayoutUpdateStrategy property. This dependency property + /// indicates the strategy class to call when AvalonDock needs to positionate a LayoutAnchorable inside an existing layout. + /// + /// Sometimes it's impossible to automatically insert an anchorable in the layout without specifing the target parent pane. + /// Set this property to an object that will be asked to insert the anchorable to the desidered position. + public ILayoutUpdateStrategy LayoutUpdateStrategy + { + get { return (ILayoutUpdateStrategy)GetValue(LayoutUpdateStrategyProperty); } + set { SetValue(LayoutUpdateStrategyProperty, value); } + } + + #endregion + + + + #endregion + + public override void OnApplyTemplate() + { + base.OnApplyTemplate(); + + SetupAutoHideWindow(); + } + + protected override void OnInitialized(EventArgs e) + { + base.OnInitialized(e); + + if (Layout.Manager == this) + { + LayoutRootPanel = CreateUIElementForModel(Layout.RootPanel) as LayoutPanelControl; + LeftSidePanel = CreateUIElementForModel(Layout.LeftSide) as LayoutAnchorSideControl; + TopSidePanel = CreateUIElementForModel(Layout.TopSide) as LayoutAnchorSideControl; + RightSidePanel = CreateUIElementForModel(Layout.RightSide) as LayoutAnchorSideControl; + BottomSidePanel = CreateUIElementForModel(Layout.BottomSide) as LayoutAnchorSideControl; + } + + + } + + void DockingManager_Loaded(object sender, RoutedEventArgs e) + { + if (!DesignerProperties.GetIsInDesignMode(this)) + { + //load windows not already loaded! + foreach (var fw in Layout.FloatingWindows.Where(fw => !_fwList.Any(fwc => fwc.Model == fw))) + _fwList.Add(CreateUIElementForModel(fw) as LayoutFloatingWindowControl); + + //create the overlaywindow if it's possible + if (IsVisible) + CreateOverlayWindow(); + FocusElementManager.SetupFocusManagement(this); + } + } + + void DockingManager_Unloaded(object sender, RoutedEventArgs e) + { + + if (!DesignerProperties.GetIsInDesignMode(this)) + { + _autoHideWindowManager?.HideAutoWindow(); + + foreach (var fw in _fwList.ToArray()) + { + //fw.Owner = null; + fw.SetParentWindowToNull(); + fw.KeepContentVisibleOnClose = true; + fw.Close(); + } + + DestroyOverlayWindow(); + FocusElementManager.FinalizeFocusManagement(this); + } + } + + internal UIElement CreateUIElementForModel(ILayoutElement model) + { + if (model is LayoutPanel) + return new LayoutPanelControl(model as LayoutPanel); + if (model is LayoutAnchorablePaneGroup) + return new LayoutAnchorablePaneGroupControl(model as LayoutAnchorablePaneGroup); + if (model is LayoutDocumentPaneGroup) + return new LayoutDocumentPaneGroupControl(model as LayoutDocumentPaneGroup); + + if (model is LayoutAnchorSide) + { + var templateModelView = new LayoutAnchorSideControl(model as LayoutAnchorSide); + templateModelView.SetBinding(LayoutAnchorSideControl.TemplateProperty, new Binding("AnchorSideTemplate") { Source = this }); + return templateModelView; + } + if (model is LayoutAnchorGroup) + { + var templateModelView = new LayoutAnchorGroupControl(model as LayoutAnchorGroup); + templateModelView.SetBinding(LayoutAnchorGroupControl.TemplateProperty, new Binding("AnchorGroupTemplate") { Source = this }); + return templateModelView; + } + + if (model is LayoutDocumentPane) + { + var templateModelView = new LayoutDocumentPaneControl(model as LayoutDocumentPane); + templateModelView.SetBinding(LayoutDocumentPaneControl.StyleProperty, new Binding("DocumentPaneControlStyle") { Source = this }); + return templateModelView; + } + if (model is LayoutAnchorablePane) + { + var templateModelView = new LayoutAnchorablePaneControl(model as LayoutAnchorablePane); + templateModelView.SetBinding(LayoutAnchorablePaneControl.StyleProperty, new Binding("AnchorablePaneControlStyle") { Source = this }); + return templateModelView; + } + + if (model is LayoutAnchorableFloatingWindow) + { + if (DesignerProperties.GetIsInDesignMode(this)) + return null; + var modelFW = model as LayoutAnchorableFloatingWindow; + var newFW = new LayoutAnchorableFloatingWindowControl(modelFW) + { + //Owner = Window.GetWindow(this) + }; + newFW.SetParentToMainWindowOf(this); + + var paneForExtensions = modelFW.RootPanel.Children.OfType().FirstOrDefault(); + if (paneForExtensions != null) + { + //ensure that floating window position is inside current (or nearest) monitor + paneForExtensions.KeepInsideNearestMonitor(); + + newFW.Left = paneForExtensions.FloatingLeft; + newFW.Top = paneForExtensions.FloatingTop; + newFW.Width = paneForExtensions.FloatingWidth; + newFW.Height = paneForExtensions.FloatingHeight; + } + + newFW.ShowInTaskbar = false; + newFW.Show(); + + // Do not set the WindowState before showing or it will be lost + if (paneForExtensions != null && paneForExtensions.IsMaximized) + { + newFW.WindowState = WindowState.Maximized; + } + + return newFW; + } + + if (model is LayoutDocumentFloatingWindow) + { + if (DesignerProperties.GetIsInDesignMode(this)) + return null; + var modelFW = model as LayoutDocumentFloatingWindow; + var newFW = new LayoutDocumentFloatingWindowControl(modelFW) + { + //Owner = Window.GetWindow(this) + }; + newFW.SetParentToMainWindowOf(this); + + var paneForExtensions = modelFW.RootDocument; + if (paneForExtensions != null) + { + //ensure that floating window position is inside current (or nearest) monitor + paneForExtensions.KeepInsideNearestMonitor(); + + newFW.Left = paneForExtensions.FloatingLeft; + newFW.Top = paneForExtensions.FloatingTop; + newFW.Width = paneForExtensions.FloatingWidth; + newFW.Height = paneForExtensions.FloatingHeight; + } + + newFW.ShowInTaskbar = false; + newFW.Show(); + + // Do not set the WindowState before showing or it will be lost + if (paneForExtensions != null && paneForExtensions.IsMaximized) + { + newFW.WindowState = WindowState.Maximized; + } + + return newFW; + } + + if (model is LayoutDocument) + { + var templateModelView = new LayoutDocumentControl() { Model = model as LayoutDocument }; + return templateModelView; + } + + return null; + } + + + + #region DocumentPaneTemplate + + /// + /// DocumentPaneTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentPaneTemplateProperty = + DependencyProperty.Register("DocumentPaneTemplate", typeof(ControlTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((ControlTemplate)null, + new PropertyChangedCallback(OnDocumentPaneTemplateChanged))); + + /// + /// Gets or sets the DocumentPaneDataTemplate property. This dependency property + /// indicates . + /// + public ControlTemplate DocumentPaneTemplate + { + get { return (ControlTemplate)GetValue(DocumentPaneTemplateProperty); } + set { SetValue(DocumentPaneTemplateProperty, value); } + } + + /// + /// Handles changes to the DocumentPaneTemplate property. + /// + private static void OnDocumentPaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentPaneTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneTemplate property. + /// + protected virtual void OnDocumentPaneTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + #region AnchorablePaneTemplate + + /// + /// AnchorablePaneTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorablePaneTemplateProperty = + DependencyProperty.Register("AnchorablePaneTemplate", typeof(ControlTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((ControlTemplate)null, + new PropertyChangedCallback(OnAnchorablePaneTemplateChanged))); + + /// + /// Gets or sets the AnchorablePaneTemplate property. This dependency property + /// indicates .... + /// + public ControlTemplate AnchorablePaneTemplate + { + get { return (ControlTemplate)GetValue(AnchorablePaneTemplateProperty); } + set { SetValue(AnchorablePaneTemplateProperty, value); } + } + + /// + /// Handles changes to the AnchorablePaneDataTemplate property. + /// + private static void OnAnchorablePaneTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorablePaneTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorablePaneDataTemplate property. + /// + protected virtual void OnAnchorablePaneTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + #region AnchorSideTemplate + + /// + /// AnchorSideTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorSideTemplateProperty = + DependencyProperty.Register("AnchorSideTemplate", typeof(ControlTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((ControlTemplate)null)); + + /// + /// Gets or sets the AnchorSideTemplate property. This dependency property + /// indicates .... + /// + public ControlTemplate AnchorSideTemplate + { + get { return (ControlTemplate)GetValue(AnchorSideTemplateProperty); } + set { SetValue(AnchorSideTemplateProperty, value); } + } + + #endregion + + #region AnchorGroupTemplate + + /// + /// AnchorGroupTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorGroupTemplateProperty = + DependencyProperty.Register("AnchorGroupTemplate", typeof(ControlTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((ControlTemplate)null)); + + /// + /// Gets or sets the AnchorGroupTemplate property. This dependency property + /// indicates the template used to render the AnchorGroup control. + /// + public ControlTemplate AnchorGroupTemplate + { + get { return (ControlTemplate)GetValue(AnchorGroupTemplateProperty); } + set { SetValue(AnchorGroupTemplateProperty, value); } + } + + #endregion + + #region AnchorTemplate + + /// + /// AnchorTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorTemplateProperty = + DependencyProperty.Register("AnchorTemplate", typeof(ControlTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((ControlTemplate)null)); + + /// + /// Gets or sets the AnchorTemplate property. This dependency property + /// indicates .... + /// + public ControlTemplate AnchorTemplate + { + get { return (ControlTemplate)GetValue(AnchorTemplateProperty); } + set { SetValue(AnchorTemplateProperty, value); } + } + + #endregion + + #region DocumentPaneControlStyle + + /// + /// DocumentPaneControlStyle Dependency Property + /// + public static readonly DependencyProperty DocumentPaneControlStyleProperty = + DependencyProperty.Register("DocumentPaneControlStyle", typeof(Style), typeof(DockingManager), + new FrameworkPropertyMetadata((Style)null, + new PropertyChangedCallback(OnDocumentPaneControlStyleChanged))); + + /// + /// Gets or sets the DocumentPaneControlStyle property. This dependency property + /// indicates .... + /// + public Style DocumentPaneControlStyle + { + get { return (Style)GetValue(DocumentPaneControlStyleProperty); } + set { SetValue(DocumentPaneControlStyleProperty, value); } + } + + /// + /// Handles changes to the DocumentPaneControlStyle property. + /// + private static void OnDocumentPaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentPaneControlStyleChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneControlStyle property. + /// + protected virtual void OnDocumentPaneControlStyleChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + #region AnchorablePaneControlStyle + + /// + /// AnchorablePaneControlStyle Dependency Property + /// + public static readonly DependencyProperty AnchorablePaneControlStyleProperty = + DependencyProperty.Register("AnchorablePaneControlStyle", typeof(Style), typeof(DockingManager), + new FrameworkPropertyMetadata((Style)null, + new PropertyChangedCallback(OnAnchorablePaneControlStyleChanged))); + + /// + /// Gets or sets the AnchorablePaneControlStyle property. This dependency property + /// indicates the style to apply to AnchorablePaneControl. + /// + public Style AnchorablePaneControlStyle + { + get { return (Style)GetValue(AnchorablePaneControlStyleProperty); } + set { SetValue(AnchorablePaneControlStyleProperty, value); } + } + + /// + /// Handles changes to the AnchorablePaneControlStyle property. + /// + private static void OnAnchorablePaneControlStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorablePaneControlStyleChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorablePaneControlStyle property. + /// + protected virtual void OnAnchorablePaneControlStyleChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + #region DocumentHeaderTemplate + + /// + /// DocumentHeaderTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentHeaderTemplateProperty = + DependencyProperty.Register("DocumentHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnDocumentHeaderTemplateChanged), + new CoerceValueCallback(CoerceDocumentHeaderTemplateValue))); + + /// + /// Gets or sets the DocumentHeaderTemplate property. This dependency property + /// indicates data template to use for document header. + /// + public DataTemplate DocumentHeaderTemplate + { + get { return (DataTemplate)GetValue(DocumentHeaderTemplateProperty); } + set { SetValue(DocumentHeaderTemplateProperty, value); } + } + + /// + /// Handles changes to the DocumentHeaderTemplate property. + /// + private static void OnDocumentHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentHeaderTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplate property. + /// + protected virtual void OnDocumentHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + /// + /// Coerces the DocumentHeaderTemplate value. + /// + private static object CoerceDocumentHeaderTemplateValue(DependencyObject d, object value) + { + if (value != null && + d.GetValue(DocumentHeaderTemplateSelectorProperty) != null) + return null; + return value; + } + + #endregion + + #region DocumentHeaderTemplateSelector + + /// + /// DocumentHeaderTemplateSelector Dependency Property + /// + public static readonly DependencyProperty DocumentHeaderTemplateSelectorProperty = + DependencyProperty.Register("DocumentHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnDocumentHeaderTemplateSelectorChanged), + new CoerceValueCallback(CoerceDocumentHeaderTemplateSelectorValue))); + + /// + /// Gets or sets the DocumentHeaderTemplateSelector property. This dependency property + /// indicates the template selector that is used when selcting the data template for the header. + /// + public DataTemplateSelector DocumentHeaderTemplateSelector + { + get { return (DataTemplateSelector)GetValue(DocumentHeaderTemplateSelectorProperty); } + set { SetValue(DocumentHeaderTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the DocumentHeaderTemplateSelector property. + /// + private static void OnDocumentHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentHeaderTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentHeaderTemplateSelector property. + /// + protected virtual void OnDocumentHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null && + DocumentHeaderTemplate != null) + DocumentHeaderTemplate = null; + + if (DocumentPaneMenuItemHeaderTemplateSelector == null) + DocumentPaneMenuItemHeaderTemplateSelector = DocumentHeaderTemplateSelector; + + } + + /// + /// Coerces the DocumentHeaderTemplateSelector value. + /// + private static object CoerceDocumentHeaderTemplateSelectorValue(DependencyObject d, object value) + { + return value; + } + + #endregion + + #region DocumentTitleTemplate + + /// + /// DocumentTitleTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentTitleTemplateProperty = + DependencyProperty.Register("DocumentTitleTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnDocumentTitleTemplateChanged), + new CoerceValueCallback(CoerceDocumentTitleTemplateValue))); + + /// + /// Gets or sets the DocumentTitleTemplate property. This dependency property + /// indicates the datatemplate to use when creating the title for a document. + /// + public DataTemplate DocumentTitleTemplate + { + get { return (DataTemplate)GetValue(DocumentTitleTemplateProperty); } + set { SetValue(DocumentTitleTemplateProperty, value); } + } + + /// + /// Handles changes to the DocumentTitleTemplate property. + /// + private static void OnDocumentTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentTitleTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplate property. + /// + protected virtual void OnDocumentTitleTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + /// + /// Coerces the DocumentTitleTemplate value. + /// + private static object CoerceDocumentTitleTemplateValue(DependencyObject d, object value) + { + if (value != null && + d.GetValue(DocumentTitleTemplateSelectorProperty) != null) + return null; + + return value; + } + + #endregion + + #region DocumentTitleTemplateSelector + + /// + /// DocumentTitleTemplateSelector Dependency Property + /// + public static readonly DependencyProperty DocumentTitleTemplateSelectorProperty = + DependencyProperty.Register("DocumentTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnDocumentTitleTemplateSelectorChanged), + new CoerceValueCallback(CoerceDocumentTitleTemplateSelectorValue))); + + /// + /// Gets or sets the DocumentTitleTemplateSelector property. This dependency property + /// indicates the data template selector to use when creating the data template for the title. + /// + public DataTemplateSelector DocumentTitleTemplateSelector + { + get { return (DataTemplateSelector)GetValue(DocumentTitleTemplateSelectorProperty); } + set { SetValue(DocumentTitleTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the DocumentTitleTemplateSelector property. + /// + private static void OnDocumentTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentTitleTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentTitleTemplateSelector property. + /// + protected virtual void OnDocumentTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null) + DocumentTitleTemplate = null; + } + + /// + /// Coerces the DocumentTitleTemplateSelector value. + /// + private static object CoerceDocumentTitleTemplateSelectorValue(DependencyObject d, object value) + { + return value; + } + + #endregion + + #region AnchorableTitleTemplate + + /// + /// AnchorableTitleTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorableTitleTemplateProperty = + DependencyProperty.Register("AnchorableTitleTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnAnchorableTitleTemplateChanged), + new CoerceValueCallback(CoerceAnchorableTitleTemplateValue))); + + /// + /// Gets or sets the AnchorableTitleTemplate property. This dependency property + /// indicates the data template to use for anchorables title. + /// + public DataTemplate AnchorableTitleTemplate + { + get { return (DataTemplate)GetValue(AnchorableTitleTemplateProperty); } + set { SetValue(AnchorableTitleTemplateProperty, value); } + } + + /// + /// Handles changes to the AnchorableTitleTemplate property. + /// + private static void OnAnchorableTitleTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorableTitleTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplate property. + /// + protected virtual void OnAnchorableTitleTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + /// + /// Coerces the AnchorableTitleTemplate value. + /// + private static object CoerceAnchorableTitleTemplateValue(DependencyObject d, object value) + { + if (value != null && + d.GetValue(AnchorableTitleTemplateSelectorProperty) != null) + return null; + return value; + } + + #endregion + + #region AnchorableTitleTemplateSelector + + /// + /// AnchorableTitleTemplateSelector Dependency Property + /// + public static readonly DependencyProperty AnchorableTitleTemplateSelectorProperty = + DependencyProperty.Register("AnchorableTitleTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnAnchorableTitleTemplateSelectorChanged))); + + /// + /// Gets or sets the AnchorableTitleTemplateSelector property. This dependency property + /// indicates selctor to use when selecting data template for the title of anchorables. + /// + public DataTemplateSelector AnchorableTitleTemplateSelector + { + get { return (DataTemplateSelector)GetValue(AnchorableTitleTemplateSelectorProperty); } + set { SetValue(AnchorableTitleTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the AnchorableTitleTemplateSelector property. + /// + private static void OnAnchorableTitleTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorableTitleTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableTitleTemplateSelector property. + /// + protected virtual void OnAnchorableTitleTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null && + AnchorableTitleTemplate != null) + AnchorableTitleTemplate = null; + } + + #endregion + + #region AnchorableHeaderTemplate + + /// + /// AnchorableHeaderTemplate Dependency Property + /// + public static readonly DependencyProperty AnchorableHeaderTemplateProperty = + DependencyProperty.Register("AnchorableHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnAnchorableHeaderTemplateChanged), + new CoerceValueCallback(CoerceAnchorableHeaderTemplateValue))); + + /// + /// Gets or sets the AnchorableHeaderTemplate property. This dependency property + /// indicates the data template to use for anchorable templates. + /// + public DataTemplate AnchorableHeaderTemplate + { + get { return (DataTemplate)GetValue(AnchorableHeaderTemplateProperty); } + set { SetValue(AnchorableHeaderTemplateProperty, value); } + } + + /// + /// Handles changes to the AnchorableHeaderTemplate property. + /// + private static void OnAnchorableHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorableHeaderTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplate property. + /// + protected virtual void OnAnchorableHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + /// + /// Coerces the AnchorableHeaderTemplate value. + /// + private static object CoerceAnchorableHeaderTemplateValue(DependencyObject d, object value) + { + if (value != null && + d.GetValue(AnchorableHeaderTemplateSelectorProperty) != null) + return null; + + return value; + } + + #endregion + + #region AnchorableHeaderTemplateSelector + + /// + /// AnchorableHeaderTemplateSelector Dependency Property + /// + public static readonly DependencyProperty AnchorableHeaderTemplateSelectorProperty = + DependencyProperty.Register("AnchorableHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnAnchorableHeaderTemplateSelectorChanged))); + + /// + /// Gets or sets the AnchorableHeaderTemplateSelector property. This dependency property + /// indicates the selector to use when selecting the data template for anchorable headers. + /// + public DataTemplateSelector AnchorableHeaderTemplateSelector + { + get { return (DataTemplateSelector)GetValue(AnchorableHeaderTemplateSelectorProperty); } + set { SetValue(AnchorableHeaderTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the AnchorableHeaderTemplateSelector property. + /// + private static void OnAnchorableHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorableHeaderTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableHeaderTemplateSelector property. + /// + protected virtual void OnAnchorableHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null) + AnchorableHeaderTemplate = null; + } + + #endregion + + protected override void OnGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) + { + //if (e.NewFocus is Grid) + // Trace.WriteLine(string.Format("DockingManager.OnGotKeyboardFocus({0})", e.NewFocus)); + base.OnGotKeyboardFocus(e); + } + + protected override void OnPreviewGotKeyboardFocus(System.Windows.Input.KeyboardFocusChangedEventArgs e) + { + Trace.WriteLine( string.Format( "DockingManager.OnPreviewGotKeyboardFocus({0})", e.NewFocus ) ); + + base.OnPreviewGotKeyboardFocus(e); + } + + protected override void OnPreviewLostKeyboardFocus(KeyboardFocusChangedEventArgs e) + { + Trace.WriteLine( string.Format( "DockingManager.OnPreviewLostKeyboardFocus({0})", e.OldFocus ) ); + base.OnPreviewLostKeyboardFocus(e); + } + + protected override void OnMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) + { + Trace.WriteLine( string.Format( "DockingManager.OnMouseLeftButtonDown([{0}])", e.GetPosition( this ) ) ); + base.OnMouseLeftButtonDown(e); + } + + protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e) + { + //Trace.WriteLine(string.Format("DockingManager.OnMouseMove([{0}])", e.GetPosition(this))); + base.OnMouseMove(e); + } + + + + #region LayoutRootPanel + + /// + /// LayoutRootPanel Dependency Property + /// + public static readonly DependencyProperty LayoutRootPanelProperty = + DependencyProperty.Register("LayoutRootPanel", typeof(LayoutPanelControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutPanelControl)null, + new PropertyChangedCallback(OnLayoutRootPanelChanged))); + + /// + /// Gets or sets the LayoutRootPanel property. This dependency property + /// indicates the layout panel control which is attached to the Layout.Root property. + /// + public LayoutPanelControl LayoutRootPanel + { + get { return (LayoutPanelControl)GetValue(LayoutRootPanelProperty); } + set { SetValue(LayoutRootPanelProperty, value); } + } + + /// + /// Handles changes to the LayoutRootPanel property. + /// + private static void OnLayoutRootPanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutRootPanelChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the LayoutRootPanel property. + /// + protected virtual void OnLayoutRootPanelChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + } + + #endregion + + #region RightSidePanel + + /// + /// RightSidePanel Dependency Property + /// + public static readonly DependencyProperty RightSidePanelProperty = + DependencyProperty.Register("RightSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, + new PropertyChangedCallback(OnRightSidePanelChanged))); + + /// + /// Gets or sets the RightSidePanel property. This dependency property + /// indicates right side anchor panel. + /// + public LayoutAnchorSideControl RightSidePanel + { + get { return (LayoutAnchorSideControl)GetValue(RightSidePanelProperty); } + set { SetValue(RightSidePanelProperty, value); } + } + + /// + /// Handles changes to the RightSidePanel property. + /// + private static void OnRightSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnRightSidePanelChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the RightSidePanel property. + /// + protected virtual void OnRightSidePanelChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + } + + #endregion + + #region LeftSidePanel + + /// + /// LeftSidePanel Dependency Property + /// + public static readonly DependencyProperty LeftSidePanelProperty = + DependencyProperty.Register("LeftSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, + new PropertyChangedCallback(OnLeftSidePanelChanged))); + + /// + /// Gets or sets the LeftSidePanel property. This dependency property + /// indicates the left side panel control. + /// + public LayoutAnchorSideControl LeftSidePanel + { + get { return (LayoutAnchorSideControl)GetValue(LeftSidePanelProperty); } + set { SetValue(LeftSidePanelProperty, value); } + } + + /// + /// Handles changes to the LeftSidePanel property. + /// + private static void OnLeftSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLeftSidePanelChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the LeftSidePanel property. + /// + protected virtual void OnLeftSidePanelChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + } + + #endregion + + #region TopSidePanel + + /// + /// TopSidePanel Dependency Property + /// + public static readonly DependencyProperty TopSidePanelProperty = + DependencyProperty.Register("TopSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, + new PropertyChangedCallback(OnTopSidePanelChanged))); + + /// + /// Gets or sets the TopSidePanel property. This dependency property + /// indicates top side control panel. + /// + public LayoutAnchorSideControl TopSidePanel + { + get { return (LayoutAnchorSideControl)GetValue(TopSidePanelProperty); } + set { SetValue(TopSidePanelProperty, value); } + } + + /// + /// Handles changes to the TopSidePanel property. + /// + private static void OnTopSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnTopSidePanelChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the TopSidePanel property. + /// + protected virtual void OnTopSidePanelChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + } + + #endregion + + #region BottomSidePanel + + /// + /// BottomSidePanel Dependency Property + /// + public static readonly DependencyProperty BottomSidePanelProperty = + DependencyProperty.Register("BottomSidePanel", typeof(LayoutAnchorSideControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutAnchorSideControl)null, + new PropertyChangedCallback(OnBottomSidePanelChanged))); + + /// + /// Gets or sets the BottomSidePanel property. This dependency property + /// indicates bottom side panel control. + /// + public LayoutAnchorSideControl BottomSidePanel + { + get { return (LayoutAnchorSideControl)GetValue(BottomSidePanelProperty); } + set { SetValue(BottomSidePanelProperty, value); } + } + + /// + /// Handles changes to the BottomSidePanel property. + /// + private static void OnBottomSidePanelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnBottomSidePanelChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the BottomSidePanel property. + /// + protected virtual void OnBottomSidePanelChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + } + + #endregion + + + #region LogicalChildren + + List _logicalChildren = new List(); + + protected override System.Collections.IEnumerator LogicalChildren + { + get + { + return _logicalChildren.Select(ch => ch.GetValueOrDefault()).GetEnumerator(); + } + } + + + internal void InternalAddLogicalChild(object element) + { + //System.Diagnostics.Trace.WriteLine("[{0}]InternalAddLogicalChild({1})", this, element); #if DEBUG - if (_logicalChildren.Select(ch => ch.GetValueOrDefault()).Contains(element)) - new InvalidOperationException(); + if (_logicalChildren.Select(ch => ch.GetValueOrDefault()).Contains(element)) + new InvalidOperationException(); #endif - if (_logicalChildren.Select(ch => ch.GetValueOrDefault()).Contains(element)) - return; - - _logicalChildren.Add(new WeakReference(element)); - AddLogicalChild(element); - } - - internal void InternalRemoveLogicalChild(object element) - { - //System.Diagnostics.Trace.WriteLine("[{0}]InternalRemoveLogicalChild({1})", this, element); - - var wrToRemove = _logicalChildren.FirstOrDefault(ch => ch.GetValueOrDefault() == element); - if (wrToRemove != null) - _logicalChildren.Remove(wrToRemove); - RemoveLogicalChild(element); - } - - void ClearLogicalChildrenList() - { - foreach (var child in _logicalChildren.Select(ch => ch.GetValueOrDefault()).ToArray()) - RemoveLogicalChild(child); - _logicalChildren.Clear(); - } - - #endregion - - #region AutoHide window - internal void ShowAutoHideWindow(LayoutAnchorControl anchor) - { - _autoHideWindowManager.ShowAutoHideWindow(anchor); - //if (_autohideArea == null) - // return; - - //if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) - // return; - - //Trace.WriteLine("ShowAutoHideWindow()"); - - //_currentAutohiddenAnchor = new WeakReference(anchor); - - //HideAutoHideWindow(anchor); - - //SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); - //AutoHideWindow.Show(); - } - - internal void HideAutoHideWindow(LayoutAnchorControl anchor) - { - _autoHideWindowManager.HideAutoWindow(anchor); - } + if (_logicalChildren.Select(ch => ch.GetValueOrDefault()).Contains(element)) + return; - - void SetupAutoHideWindow() - { - _autohideArea = GetTemplateChild("PART_AutoHideArea") as FrameworkElement; - - if (_autoHideWindowManager != null) - _autoHideWindowManager.HideAutoWindow(); - else - _autoHideWindowManager = new AutoHideWindowManager(this); - - if (AutoHideWindow != null) - AutoHideWindow.Dispose(); - - SetAutoHideWindow(new LayoutAutoHideWindowControl()); - } - - AutoHideWindowManager _autoHideWindowManager; - - FrameworkElement _autohideArea; - internal FrameworkElement GetAutoHideAreaElement() - { - return _autohideArea; - } - - #region AutoHideWindow - - /// - /// AutoHideWindow Read-Only Dependency Property - /// - private static readonly DependencyPropertyKey AutoHideWindowPropertyKey - = DependencyProperty.RegisterReadOnly("AutoHideWindow", typeof(LayoutAutoHideWindowControl), typeof(DockingManager), - new FrameworkPropertyMetadata((LayoutAutoHideWindowControl)null, - new PropertyChangedCallback(OnAutoHideWindowChanged))); - - public static readonly DependencyProperty AutoHideWindowProperty - = AutoHideWindowPropertyKey.DependencyProperty; - - /// - /// Gets the AutoHideWindow property. This dependency property - /// indicates the currently shown autohide window. - /// - public LayoutAutoHideWindowControl AutoHideWindow - { - get { return (LayoutAutoHideWindowControl)GetValue(AutoHideWindowProperty); } - } - - /// - /// Provides a secure method for setting the AutoHideWindow property. - /// This dependency property indicates the currently shown autohide window. - /// - /// The new value for the property. - protected void SetAutoHideWindow(LayoutAutoHideWindowControl value) - { - SetValue(AutoHideWindowPropertyKey, value); - } - - /// - /// Handles changes to the AutoHideWindow property. - /// - private static void OnAutoHideWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAutoHideWindowChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AutoHideWindow property. - /// - protected virtual void OnAutoHideWindowChanged(DependencyPropertyChangedEventArgs e) - { - if (e.OldValue != null) - InternalRemoveLogicalChild(e.OldValue); - if (e.NewValue != null) - InternalAddLogicalChild(e.NewValue); - - } - - #endregion - - - - #endregion - // #region AutoHide window - //WeakReference _currentAutohiddenAnchor = null; - //internal void ShowAutoHideWindow(LayoutAnchorControl anchor) - //{ - // if (_autohideArea == null) - // return; - - // if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) - // return; - - // Trace.WriteLine("ShowAutoHideWindow()"); - - // _currentAutohiddenAnchor = new WeakReference(anchor); - - // HideAutoHideWindow(anchor); - - // SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); - //} - - //internal void HideAutoHideWindow(LayoutAnchorControl anchor) - //{ - // if (AutoHideWindow != null) - // { - // if (anchor == _currentAutohiddenAnchor.GetValueOrDefault()) - // { - // Trace.WriteLine("AutoHideWindow()"); - // AutoHideWindow.Dispose(); - // SetAutoHideWindow(null); - // } - // } - //} - - //FrameworkElement _autohideArea; - //internal FrameworkElement GetAutoHideAreaElement() - //{ - // return _autohideArea; - //} - - //void SetupAutoHideArea() - //{ - // _autohideArea = GetTemplateChild("PART_AutoHideArea") as FrameworkElement; - //} - - // #region AutoHideWindow - - ///// - ///// AutoHideWindow Read-Only Dependency Property - ///// - //private static readonly DependencyPropertyKey AutoHideWindowPropertyKey - // = DependencyProperty.RegisterReadOnly("AutoHideWindow", typeof(LayoutAutoHideWindowControl), typeof(DockingManager), - // new FrameworkPropertyMetadata((LayoutAutoHideWindowControl)null, - // new PropertyChangedCallback(OnAutoHideWindowChanged))); - - //public static readonly DependencyProperty AutoHideWindowProperty - // = AutoHideWindowPropertyKey.DependencyProperty; - - ///// - ///// Gets the AutoHideWindow property. This dependency property - ///// indicates the currently shown autohide window. - ///// - //public LayoutAutoHideWindowControl AutoHideWindow - //{ - // get { return (LayoutAutoHideWindowControl)GetValue(AutoHideWindowProperty); } - //} - - ///// - ///// Provides a secure method for setting the AutoHideWindow property. - ///// This dependency property indicates the currently shown autohide window. - ///// - ///// The new value for the property. - //protected void SetAutoHideWindow(LayoutAutoHideWindowControl value) - //{ - // SetValue(AutoHideWindowPropertyKey, value); - //} - - ///// - ///// Handles changes to the AutoHideWindow property. - ///// - //private static void OnAutoHideWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - //{ - // ((DockingManager)d).OnAutoHideWindowChanged(e); - //} - - ///// - ///// Provides derived classes an opportunity to handle changes to the AutoHideWindow property. - ///// - //protected virtual void OnAutoHideWindowChanged(DependencyPropertyChangedEventArgs e) - //{ - // if (e.OldValue != null) - // ((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(e.OldValue); - // if (e.NewValue != null) - // ((ILogicalChildrenContainer)this).InternalAddLogicalChild(e.NewValue); - //} - - // #endregion - - - - // #endregion - - #region Floating Windows - List _fwList = new List(); - - internal void StartDraggingFloatingWindowForContent(LayoutContent contentModel, bool startDrag = true) - { - if (!contentModel.CanFloat) - return; - var contentModelAsAnchorable = contentModel as LayoutAnchorable; - if (contentModelAsAnchorable != null && - contentModelAsAnchorable.IsAutoHidden) - contentModelAsAnchorable.ToggleAutoHide(); - - var parentPane = contentModel.Parent as ILayoutPane; - var parentPaneAsPositionableElement = contentModel.Parent as ILayoutPositionableElement; - var parentPaneAsWithActualSize = contentModel.Parent as ILayoutPositionableElementWithActualSize; - var contentModelParentChildrenIndex = parentPane.Children.ToList().IndexOf(contentModel); - - if (contentModel.FindParent() == null) - { - ((ILayoutPreviousContainer)contentModel).PreviousContainer = parentPane; - contentModel.PreviousContainerIndex = contentModelParentChildrenIndex; - } - - parentPane.RemoveChildAt(contentModelParentChildrenIndex); - - double fwWidth = contentModel.FloatingWidth; - double fwHeight = contentModel.FloatingHeight; - - if (fwWidth == 0.0) - fwWidth = parentPaneAsPositionableElement.FloatingWidth; - if (fwHeight == 0.0) - fwHeight = parentPaneAsPositionableElement.FloatingHeight; - - if (fwWidth == 0.0) - fwWidth = parentPaneAsWithActualSize.ActualWidth; - if (fwHeight == 0.0) - fwHeight = parentPaneAsWithActualSize.ActualHeight; - - LayoutFloatingWindow fw; - LayoutFloatingWindowControl fwc; - if (contentModel is LayoutAnchorable) - { - var anchorableContent = contentModel as LayoutAnchorable; - fw = new LayoutAnchorableFloatingWindow() - { - RootPanel = new LayoutAnchorablePaneGroup( - new LayoutAnchorablePane(anchorableContent) - { - 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); - - fwc = new LayoutAnchorableFloatingWindowControl( - fw as LayoutAnchorableFloatingWindow) - { - Width = fwWidth, - Height = fwHeight, - Left = contentModel.FloatingLeft, - Top = contentModel.FloatingTop - }; - } - else - { - var anchorableDocument = contentModel as LayoutDocument; - fw = new LayoutDocumentFloatingWindow() - { - RootDocument = anchorableDocument - }; - - Layout.FloatingWindows.Add(fw); - - fwc = new LayoutDocumentFloatingWindowControl( - fw as LayoutDocumentFloatingWindow) - { - Width = fwWidth, - Height = fwHeight, - Left = contentModel.FloatingLeft, - Top = contentModel.FloatingTop - }; - } - - - //fwc.Owner = Window.GetWindow(this); - //fwc.SetParentToMainWindowOf(this); - - - _fwList.Add(fwc); - - Layout.CollectGarbage(); - - UpdateLayout(); - - Dispatcher.BeginInvoke(new Action(() => - { - if (startDrag) - fwc.AttachDrag(); - fwc.Show(); - }), DispatcherPriority.Send); - } - - internal void StartDraggingFloatingWindowForPane(LayoutAnchorablePane paneModel) - { - if (paneModel.Children.Any(c => !c.CanFloat)) - return; - var paneAsPositionableElement = paneModel as ILayoutPositionableElement; - var paneAsWithActualSize = paneModel as ILayoutPositionableElementWithActualSize; - - double fwWidth = paneAsPositionableElement.FloatingWidth; - double fwHeight = paneAsPositionableElement.FloatingHeight; - double fwLeft = paneAsPositionableElement.FloatingLeft; - double fwTop = paneAsPositionableElement.FloatingTop; - - - - if (fwWidth == 0.0) - fwWidth = paneAsWithActualSize.ActualWidth; - if (fwHeight == 0.0) - fwHeight = paneAsWithActualSize.ActualHeight; - - var destPane = new LayoutAnchorablePane() - { - DockWidth = paneAsPositionableElement.DockWidth, - DockHeight = paneAsPositionableElement.DockHeight, - DockMinHeight = paneAsPositionableElement.DockMinHeight, - DockMinWidth = paneAsPositionableElement.DockMinWidth, - FloatingLeft = paneAsPositionableElement.FloatingLeft, - FloatingTop = paneAsPositionableElement.FloatingTop, - FloatingWidth = paneAsPositionableElement.FloatingWidth, - FloatingHeight = paneAsPositionableElement.FloatingHeight, - }; - - bool savePreviousContainer = paneModel.FindParent() == null; - int currentSelectedContentIndex = paneModel.SelectedContentIndex; - while (paneModel.Children.Count > 0) - { - var contentModel = paneModel.Children[paneModel.Children.Count - 1] as LayoutAnchorable; - - if (savePreviousContainer) - { - var contentModelAsPreviousContainer = contentModel as ILayoutPreviousContainer; - contentModelAsPreviousContainer.PreviousContainer = paneModel; - contentModel.PreviousContainerIndex = paneModel.Children.Count - 1; - } - - paneModel.RemoveChildAt(paneModel.Children.Count - 1); - destPane.Children.Insert(0, contentModel); - } - - if (destPane.Children.Count > 0) - { - destPane.SelectedContentIndex = currentSelectedContentIndex; - } - - - LayoutFloatingWindow fw; - LayoutFloatingWindowControl fwc; - fw = new LayoutAnchorableFloatingWindow() - { - RootPanel = new LayoutAnchorablePaneGroup( - destPane) - { - DockHeight = destPane.DockHeight, - DockWidth = destPane.DockWidth, - DockMinHeight = destPane.DockMinHeight, - DockMinWidth = destPane.DockMinWidth, - } - }; - - Layout.FloatingWindows.Add(fw); - - fwc = new LayoutAnchorableFloatingWindowControl( - fw as LayoutAnchorableFloatingWindow) - { - Width = fwWidth, - Height = fwHeight - }; - - - - //fwc.Owner = Window.GetWindow(this); - //fwc.SetParentToMainWindowOf(this); - - - _fwList.Add(fwc); - - Layout.CollectGarbage(); - - InvalidateArrange(); - - fwc.AttachDrag(); - fwc.Show(); - - } - - internal IEnumerable GetFloatingWindowsByZOrder() - { - var parentWindow = Window.GetWindow(this); - - if (parentWindow == null) - yield break; - - IntPtr windowParentHanlde = new WindowInteropHelper(parentWindow).Handle; - - IntPtr currentHandle = Win32Helper.GetWindow(windowParentHanlde, (uint)Win32Helper.GetWindow_Cmd.GW_HWNDFIRST); - while (currentHandle != IntPtr.Zero) - { - LayoutFloatingWindowControl ctrl = _fwList.FirstOrDefault(fw => new WindowInteropHelper(fw).Handle == currentHandle); - if (ctrl != null && ctrl.Model.Root.Manager == this) - yield return ctrl; - - currentHandle = Win32Helper.GetWindow(currentHandle, (uint)Win32Helper.GetWindow_Cmd.GW_HWNDNEXT); - } - } - - internal void RemoveFloatingWindow(LayoutFloatingWindowControl floatingWindow) - { - _fwList.Remove(floatingWindow); - } - - public IEnumerable FloatingWindows - { - get { return _fwList; } - } - #endregion - - #region OverlayWindow - - bool IOverlayWindowHost.HitTest(Point dragPoint) - { - Rect detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); - return detectionRect.Contains(dragPoint); - } - - DockingManager IOverlayWindowHost.Manager - { - get { return this; } - } - - 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; - } - - void DestroyOverlayWindow() - { - if (_overlayWindow != null) - { - _overlayWindow.Close(); - _overlayWindow = null; - } - } - - IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow) - { - //Trace.WriteLine("ShowOverlayWindow"); - CreateOverlayWindow(); - _overlayWindow.Owner = draggingWindow; - _overlayWindow.EnableDropTargets(); - _overlayWindow.Show(); - return _overlayWindow; - } - - void IOverlayWindowHost.HideOverlayWindow() - { - //Trace.WriteLine("HideOverlayWindow"); - _areas = null; - _overlayWindow.Owner = null; - _overlayWindow.HideDropTargets(); - } - - List _areas = null; - - IEnumerable IOverlayWindowHost.GetDropAreas(LayoutFloatingWindowControl draggingWindow) - { - if (_areas != null) - return _areas; - - bool isDraggingDocuments = draggingWindow.Model is LayoutDocumentFloatingWindow; - - _areas = new List(); - - if (!isDraggingDocuments) - { - _areas.Add(new DropArea( - this, - DropAreaType.DockingManager)); - - foreach (var areaHost in this.FindVisualChildren()) - { - if (areaHost.Model.Descendents().Any()) - { - _areas.Add(new DropArea( - areaHost, - DropAreaType.AnchorablePane)); - } - } - } - - foreach (var areaHost in this.FindVisualChildren()) - { - _areas.Add(new DropArea( - areaHost, - DropAreaType.DocumentPane)); - } - - foreach (var areaHost in this.FindVisualChildren()) - { - var documentGroupModel = areaHost.Model as LayoutDocumentPaneGroup; - if (documentGroupModel.Children.Where(c => c.IsVisible).Count() == 0) - { - _areas.Add(new DropArea( - areaHost, - DropAreaType.DocumentPaneGroup)); - } - } - - return _areas; - } - - protected override Size ArrangeOverride(Size arrangeBounds) - { - _areas = null; - return base.ArrangeOverride(arrangeBounds); - } - - #endregion - - #region LayoutDocument & LayoutAnchorable Templates - - #region LayoutItemTemplate - - /// - /// LayoutItemTemplate Dependency Property - /// - public static readonly DependencyProperty LayoutItemTemplateProperty = - DependencyProperty.Register("LayoutItemTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnLayoutItemTemplateChanged))); - - /// - /// Gets or sets the AnchorableTemplate property. This dependency property - /// indicates the template to use to render anchorable and document contents. - /// - public DataTemplate LayoutItemTemplate - { - get { return (DataTemplate)GetValue(LayoutItemTemplateProperty); } - set { SetValue(LayoutItemTemplateProperty, value); } - } - - /// - /// Handles changes to the AnchorableTemplate property. - /// - private static void OnLayoutItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutItemTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorableTemplate property. - /// - protected virtual void OnLayoutItemTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - #region LayoutItemTemplateSelector - - /// - /// LayoutItemTemplateSelector Dependency Property - /// - public static readonly DependencyProperty LayoutItemTemplateSelectorProperty = - DependencyProperty.Register("LayoutItemTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnLayoutItemTemplateSelectorChanged))); - - /// - /// Gets or sets the LayoutItemTemplateSelector property. This dependency property - /// indicates selector object to use for anchorable templates. - /// - public DataTemplateSelector LayoutItemTemplateSelector - { - get { return (DataTemplateSelector)GetValue(LayoutItemTemplateSelectorProperty); } - set { SetValue(LayoutItemTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the LayoutItemTemplateSelector property. - /// - private static void OnLayoutItemTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutItemTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemTemplateSelector property. - /// - protected virtual void OnLayoutItemTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion - - - #endregion - - #region DocumentsSource - - /// - /// DocumentsSource Dependency Property - /// - public static readonly DependencyProperty DocumentsSourceProperty = - DependencyProperty.Register("DocumentsSource", typeof(IEnumerable), typeof(DockingManager), - new FrameworkPropertyMetadata((IEnumerable)null, - new PropertyChangedCallback(OnDocumentsSourceChanged))); - - /// - /// Gets or sets the DocumentsSource property. This dependency property - /// indicates the source collection of documents. - /// - public IEnumerable DocumentsSource - { - get { return (IEnumerable)GetValue(DocumentsSourceProperty); } - set { SetValue(DocumentsSourceProperty, value); } - } - - /// - /// Handles changes to the DocumentsSource property. - /// - private static void OnDocumentsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentsSourceChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentsSource property. - /// - protected virtual void OnDocumentsSourceChanged(DependencyPropertyChangedEventArgs e) - { - DetachDocumentsSource(Layout, e.OldValue as IEnumerable); - AttachDocumentsSource(Layout, e.NewValue as IEnumerable); - } - - - void AttachDocumentsSource(LayoutRoot layout, IEnumerable documentsSource) - { - if (documentsSource == null) - return; - - if (layout == null) - return; - - //if (layout.Descendents().OfType().Any()) - // throw new InvalidOperationException("Unable to set the DocumentsSource property if LayoutDocument objects are already present in the model"); - var documentsImported = layout.Descendents().OfType().Select(d => d.Content).ToArray(); - var documents = documentsSource as IEnumerable; - var listOfDocumentsToImport = new List(documents.OfType()); - - foreach (var document in listOfDocumentsToImport.ToArray()) - { - if (documentsImported.Contains(document)) - listOfDocumentsToImport.Remove(document); - } - - - LayoutDocumentPane documentPane = null; - if (layout.LastFocusedDocument != null) - { - documentPane = layout.LastFocusedDocument.Parent as LayoutDocumentPane; - } - - if (documentPane == null) - { - documentPane = layout.Descendents().OfType().FirstOrDefault(); - } - - //if (documentPane == null) - // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - _suspendLayoutItemCreation = true; - foreach (var documentContentToImport in listOfDocumentsToImport) - { - - //documentPane.Children.Add(new LayoutDocument() { Content = documentToImport }); - - var documentToImport = new LayoutDocument() - { - Content = documentContentToImport - }; - - bool added = false; - if (LayoutUpdateStrategy != null) - { - added = LayoutUpdateStrategy.BeforeInsertDocument(layout, documentToImport, documentPane); - } - - if (!added) - { - if (documentPane == null) - throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - documentPane.Children.Add(documentToImport); - added = true; - } - - if (LayoutUpdateStrategy != null) - LayoutUpdateStrategy.AfterInsertDocument(layout, documentToImport); - - - CreateDocumentLayoutItem(documentToImport); - - } - _suspendLayoutItemCreation = true; - - - var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; - if (documentsSourceAsNotifier != null) - documentsSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(documentsSourceElementsChanged); - } - - internal bool SuspendDocumentsSourceBinding = false; - - void documentsSourceElementsChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (Layout == null) - return; - - //When deserializing documents are created automatically by the deserializer - if (SuspendDocumentsSourceBinding) - return; - - //handle remove - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.OldItems != null) - { - var documentsToRemove = Layout.Descendents().OfType().Where(d => e.OldItems.Contains(d.Content)).ToArray(); - foreach (var documentToRemove in documentsToRemove) - { - (documentToRemove.Parent as ILayoutContainer).RemoveChild( - documentToRemove); - } - } - } - - //handle add - if (e.NewItems != null && - (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace)) - { - if (e.NewItems != null) - { - LayoutDocumentPane documentPane = null; - if (Layout.LastFocusedDocument != null) - { - documentPane = Layout.LastFocusedDocument.Parent as LayoutDocumentPane; - } - - if (documentPane == null) - { - documentPane = Layout.Descendents().OfType().FirstOrDefault(); - } - - //if (documentPane == null) - // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - _suspendLayoutItemCreation = true; - - foreach (var documentContentToImport in e.NewItems) - { - var documentToImport = new LayoutDocument() - { - Content = documentContentToImport - }; - - bool added = false; - if (LayoutUpdateStrategy != null) - { - added = LayoutUpdateStrategy.BeforeInsertDocument(Layout, documentToImport, documentPane); - } - - if (!added) - { - if (documentPane == null) - throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); - - documentPane.Children.Add(documentToImport); - added = true; - } - - if (LayoutUpdateStrategy != null) - { - LayoutUpdateStrategy.AfterInsertDocument(Layout, documentToImport); - } - - - var root = documentToImport.Root; - - if (root != null && root.Manager == this) - { - CreateDocumentLayoutItem(documentToImport); - } - } - _suspendLayoutItemCreation = false; - } - } - - if (e.Action == NotifyCollectionChangedAction.Reset) - { - //NOTE: I'm going to clear every document present in layout but - //some documents may have been added directly to the layout, for now I clear them too - var documentsToRemove = Layout.Descendents().OfType().ToArray(); - foreach (var documentToRemove in documentsToRemove) - { - (documentToRemove.Parent as ILayoutContainer).RemoveChild( - documentToRemove); - } - } - - if (Layout != null) - { - Layout.CollectGarbage(); - } - } - - void DetachDocumentsSource(LayoutRoot layout, IEnumerable documentsSource) - { - if (documentsSource == null) - return; - - if (layout == null) - return; - - var documentsToRemove = layout.Descendents().OfType() - .Where(d => documentsSource.Contains(d.Content)).ToArray(); - - foreach (var documentToRemove in documentsToRemove) - { - (documentToRemove.Parent as ILayoutContainer).RemoveChild( - documentToRemove); - } - - var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; - if (documentsSourceAsNotifier != null) - documentsSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler(documentsSourceElementsChanged); - } - - - #endregion - - #region DocumentCloseCommand - - internal void _ExecuteCloseCommand(LayoutDocument document) - { - if (DocumentClosing != null) - { - var evargs = new DocumentClosingEventArgs(document); - DocumentClosing(this, evargs); - if (evargs.Cancel) - return; - } - - if (!document.TestCanClose()) - return; - - document.Close(); - - if (DocumentClosed != null) - { - var evargs = new DocumentClosedEventArgs(document); - DocumentClosed(this, evargs); - } - } - - /// - /// Event fired when a document is about to be closed - /// - /// Subscribers have the opportuniy to cancel the operation. - public event EventHandler DocumentClosing; - - /// - /// Event fired after a document is closed - /// - public event EventHandler DocumentClosed; - - - - #endregion - - internal void _ExecuteCloseAllButThisCommand(LayoutContent contentSelected) - { - foreach (var contentToClose in Layout.Descendents().OfType().Where(d => d != contentSelected && (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) - { - if (!contentToClose.CanClose) - continue; - - var layoutItem = GetLayoutItemFromModel(contentToClose); - if (layoutItem.CloseCommand != null) - { - if (layoutItem.CloseCommand.CanExecute(null)) - layoutItem.CloseCommand.Execute(null); - } - else - { - if (contentToClose is LayoutDocument) - _ExecuteCloseCommand(contentToClose as LayoutDocument); - else if (contentToClose is LayoutAnchorable) - _ExecuteCloseCommand(contentToClose as LayoutAnchorable); - } - } - } - - #region DocumentContextMenu - - /// - /// DocumentContextMenu Dependency Property - /// - public static readonly DependencyProperty DocumentContextMenuProperty = - DependencyProperty.Register("DocumentContextMenu", typeof(ContextMenu), typeof(DockingManager), - new FrameworkPropertyMetadata((ContextMenu)null)); - - /// - /// Gets or sets the DocumentContextMenu property. This dependency property - /// indicates context menu to show for documents. - /// - public ContextMenu DocumentContextMenu - { - get { return (ContextMenu)GetValue(DocumentContextMenuProperty); } - set { SetValue(DocumentContextMenuProperty, value); } - } - - #endregion - - #region AnchorablesSource - - /// - /// AnchorablesSource Dependency Property - /// - public static readonly DependencyProperty AnchorablesSourceProperty = - DependencyProperty.Register("AnchorablesSource", typeof(IEnumerable), typeof(DockingManager), - new FrameworkPropertyMetadata((IEnumerable)null, - new PropertyChangedCallback(OnAnchorablesSourceChanged))); - - /// - /// Gets or sets the AnchorablesSource property. This dependency property - /// indicates source collection of anchorables. - /// - public IEnumerable AnchorablesSource - { - get { return (IEnumerable)GetValue(AnchorablesSourceProperty); } - set { SetValue(AnchorablesSourceProperty, value); } - } - - /// - /// Handles changes to the AnchorablesSource property. - /// - private static void OnAnchorablesSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnAnchorablesSourceChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the AnchorablesSource property. - /// - protected virtual void OnAnchorablesSourceChanged(DependencyPropertyChangedEventArgs e) - { - DetachAnchorablesSource(Layout, e.OldValue as IEnumerable); - AttachAnchorablesSource(Layout, e.NewValue as IEnumerable); - } - - void AttachAnchorablesSource(LayoutRoot layout, IEnumerable anchorablesSource) - { - if (anchorablesSource == null) - return; - - if (layout == null) - return; - - //if (layout.Descendents().OfType().Any()) - // throw new InvalidOperationException("Unable to set the AnchorablesSource property if LayoutAnchorable objects are already present in the model"); - var anchorablesImported = layout.Descendents().OfType().Select(d => d.Content).ToArray(); - var anchorables = anchorablesSource as IEnumerable; - var listOfAnchorablesToImport = new List(anchorables.OfType()); - - foreach (var document in listOfAnchorablesToImport.ToArray()) - { - if (anchorablesImported.Contains(document)) - listOfAnchorablesToImport.Remove(document); - } - - LayoutAnchorablePane anchorablePane = null; - if (layout.ActiveContent != null) - { - //look for active content parent pane - anchorablePane = layout.ActiveContent.Parent as LayoutAnchorablePane; - } - - if (anchorablePane == null) - { - //look for a pane on the right side - anchorablePane = layout.Descendents().OfType().Where(pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right).FirstOrDefault(); - } - - if (anchorablePane == null) - { - //look for an available pane - anchorablePane = layout.Descendents().OfType().FirstOrDefault(); - } - - _suspendLayoutItemCreation = true; - foreach (var anchorableContentToImport in listOfAnchorablesToImport) - { - var anchorableToImport = new LayoutAnchorable() - { - Content = anchorableContentToImport - }; - - bool added = false; - if (LayoutUpdateStrategy != null) - { - added = LayoutUpdateStrategy.BeforeInsertAnchorable(layout, anchorableToImport, anchorablePane); - } - - if (!added) - { - if (anchorablePane == null) - { - var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; - if (layout.RootPanel != null) - { - mainLayoutPanel.Children.Add(layout.RootPanel); - } - - layout.RootPanel = mainLayoutPanel; - anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength(200.0, GridUnitType.Pixel) }; - mainLayoutPanel.Children.Add(anchorablePane); - } - - anchorablePane.Children.Add(anchorableToImport); - added = true; - } - - if (LayoutUpdateStrategy != null) - LayoutUpdateStrategy.AfterInsertAnchorable(layout, anchorableToImport); - - - CreateAnchorableLayoutItem(anchorableToImport); - - } - - _suspendLayoutItemCreation = false; - - var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; - if (anchorablesSourceAsNotifier != null) - anchorablesSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(anchorablesSourceElementsChanged); - } - - internal bool SuspendAnchorablesSourceBinding = false; - - void anchorablesSourceElementsChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (Layout == null) - return; - - //When deserializing documents are created automatically by the deserializer - if (SuspendAnchorablesSourceBinding) - return; - - //handle remove - if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) - { - if (e.OldItems != null) - { - var anchorablesToRemove = Layout.Descendents().OfType().Where(d => e.OldItems.Contains(d.Content)).ToArray(); - foreach (var anchorableToRemove in anchorablesToRemove) - { - (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( - anchorableToRemove); - } - } - } - - //handle add - if (e.NewItems != null && - (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || - e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace)) - { - if (e.NewItems != null) - { - LayoutAnchorablePane anchorablePane = null; - - if (Layout.ActiveContent != null) - { - //look for active content parent pane - anchorablePane = Layout.ActiveContent.Parent as LayoutAnchorablePane; - } - - if (anchorablePane == null) - { - //look for a pane on the right side - anchorablePane = Layout.Descendents().OfType().Where(pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right).FirstOrDefault(); - } - - if (anchorablePane == null) - { - //look for an available pane - anchorablePane = Layout.Descendents().OfType().FirstOrDefault(); - } - - _suspendLayoutItemCreation = true; - foreach (var anchorableContentToImport in e.NewItems) - { - var anchorableToImport = new LayoutAnchorable() - { - Content = anchorableContentToImport - }; - - bool added = false; - if (LayoutUpdateStrategy != null) - { - added = LayoutUpdateStrategy.BeforeInsertAnchorable(Layout, anchorableToImport, anchorablePane); - } - - if (!added) - { - if (anchorablePane == null) - { - var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; - if (Layout.RootPanel != null) - { - mainLayoutPanel.Children.Add(Layout.RootPanel); - } - - Layout.RootPanel = mainLayoutPanel; - anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength(200.0, GridUnitType.Pixel) }; - mainLayoutPanel.Children.Add(anchorablePane); - } - - anchorablePane.Children.Add(anchorableToImport); - added = true; - } - - if (LayoutUpdateStrategy != null) - { - LayoutUpdateStrategy.AfterInsertAnchorable(Layout, anchorableToImport); - } - - var root = anchorableToImport.Root; - - if (root != null && root.Manager == this) - { - CreateAnchorableLayoutItem(anchorableToImport); - } - - } - _suspendLayoutItemCreation = false; - } - } - - if (e.Action == NotifyCollectionChangedAction.Reset) - { - //NOTE: I'm going to clear every anchorable present in layout but - //some anchorable may have been added directly to the layout, for now I clear them too - var anchorablesToRemove = Layout.Descendents().OfType().ToArray(); - foreach (var anchorableToRemove in anchorablesToRemove) - { - (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( - anchorableToRemove); - } - } - - if (Layout != null) - Layout.CollectGarbage(); - } - - void DetachAnchorablesSource(LayoutRoot layout, IEnumerable anchorablesSource) - { - if (anchorablesSource == null) - return; - - if (layout == null) - return; - - var anchorablesToRemove = layout.Descendents().OfType() - .Where(d => anchorablesSource.Contains(d.Content)).ToArray(); - - foreach (var anchorableToRemove in anchorablesToRemove) - { - (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( - anchorableToRemove); - } - - var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; - if (anchorablesSourceAsNotifier != null) - anchorablesSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler(anchorablesSourceElementsChanged); - } - - #endregion - - internal void _ExecuteCloseCommand(LayoutAnchorable anchorable) - { - var model = anchorable as LayoutAnchorable; - if (model != null && model.TestCanClose()) - { - if (model.IsAutoHidden) - model.ToggleAutoHide(); - - model.Close(); - return; - } - } - - internal void _ExecuteHideCommand(LayoutAnchorable anchorable) - { - var model = anchorable as LayoutAnchorable; - if (model != null) - { - //by default hide the anchorable - model.Hide(); - } - } - - internal void _ExecuteAutoHideCommand(LayoutAnchorable _anchorable) - { - _anchorable.ToggleAutoHide(); - } - - internal void _ExecuteFloatCommand(LayoutContent contentToFloat) - { - contentToFloat.Float(); - } - - internal void _ExecuteDockCommand(LayoutAnchorable anchorable) - { - anchorable.Dock(); - } - - internal void _ExecuteDockAsDocumentCommand(LayoutContent content) - { - content.DockAsDocument(); - } - - #region ActiveContent - - /// - /// ActiveContent Dependency Property - /// - public static readonly DependencyProperty ActiveContentProperty = - DependencyProperty.Register("ActiveContent", typeof(object), typeof(DockingManager), - new FrameworkPropertyMetadata((object)null, - new PropertyChangedCallback(OnActiveContentChanged))); - - /// - /// Gets or sets the ActiveContent property. This dependency property - /// indicates the content currently active. - /// - public object ActiveContent - { - get { return (object)GetValue(ActiveContentProperty); } - set { SetValue(ActiveContentProperty, value); } - } - - /// - /// Handles changes to the ActiveContent property. - /// - private static void OnActiveContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).InternalSetActiveContent(e.NewValue); - ((DockingManager)d).OnActiveContentChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the ActiveContent property. - /// - protected virtual void OnActiveContentChanged(DependencyPropertyChangedEventArgs e) - { - if (ActiveContentChanged != null) - ActiveContentChanged(this, EventArgs.Empty); - } - - - bool _insideInternalSetActiveContent = false; - void InternalSetActiveContent(object contentObject) - { - var layoutContent = Layout.Descendents().OfType().FirstOrDefault(lc => lc == contentObject || lc.Content == contentObject); - _insideInternalSetActiveContent = true; - Layout.ActiveContent = layoutContent; - _insideInternalSetActiveContent = false; - } - - public event EventHandler ActiveContentChanged; - - #endregion - - #region AnchorableContextMenu - - /// - /// AnchorableContextMenu Dependency Property - /// - public static readonly DependencyProperty AnchorableContextMenuProperty = - DependencyProperty.Register("AnchorableContextMenu", typeof(ContextMenu), typeof(DockingManager), - new FrameworkPropertyMetadata((ContextMenu)null)); - - /// - /// Gets or sets the AnchorableContextMenu property. This dependency property - /// indicates the context menu to show up for anchorables. - /// - public ContextMenu AnchorableContextMenu - { - get { return (ContextMenu)GetValue(AnchorableContextMenuProperty); } - set { SetValue(AnchorableContextMenuProperty, value); } - } - - #endregion - - #region Theme - - /// - /// Theme Dependency Property - /// - public static readonly DependencyProperty ThemeProperty = - DependencyProperty.Register("Theme", typeof(Theme), typeof(DockingManager), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnThemeChanged))); - - /// - /// Gets or sets the Theme property. This dependency property - /// indicates the theme to use for AvalonDock controls. - /// - public Theme Theme - { - get { return (Theme)GetValue(ThemeProperty); } - set { SetValue(ThemeProperty, value); } - } - - /// - /// Handles changes to the Theme property. - /// - private static void OnThemeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnThemeChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the Theme property. - /// - protected virtual void OnThemeChanged(DependencyPropertyChangedEventArgs e) - { - var oldTheme = e.OldValue as Theme; - var newTheme = e.NewValue as Theme; - var resources = this.Resources; - if (oldTheme != null) - { - var resourceDictionaryToRemove = - resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); - if (resourceDictionaryToRemove != null) - resources.MergedDictionaries.Remove( - resourceDictionaryToRemove); - } - - if (newTheme != null) - { - resources.MergedDictionaries.Add(new ResourceDictionary() { Source = newTheme.GetResourceUri() }); - } - - foreach (var fwc in _fwList) - fwc.UpdateThemeResources(oldTheme); - - if (_navigatorWindow != null) - _navigatorWindow.UpdateThemeResources(); - - if (_overlayWindow != null) - _overlayWindow.UpdateThemeResources(); - } - - #endregion - - #region GridSplitterWidth - - /// - /// GridSplitterWidth Dependency Property - /// - public static readonly DependencyProperty GridSplitterWidthProperty = - DependencyProperty.Register("GridSplitterWidth", typeof(double), typeof(DockingManager), - new FrameworkPropertyMetadata((double)6.0)); - - /// - /// Gets or sets the GridSplitterWidth property. This dependency property - /// indicates width of grid splitters. - /// - public double GridSplitterWidth - { - get { return (double)GetValue(GridSplitterWidthProperty); } - set { SetValue(GridSplitterWidthProperty, value); } - } - - #endregion - - #region GridSplitterHeight - - /// - /// GridSplitterHeight Dependency Property - /// - public static readonly DependencyProperty GridSplitterHeightProperty = - DependencyProperty.Register("GridSplitterHeight", typeof(double), typeof(DockingManager), - new FrameworkPropertyMetadata((double)6.0)); - - /// - /// Gets or sets the GridSplitterHeight property. This dependency property - /// indicates height of grid splitters. - /// - public double GridSplitterHeight - { - get { return (double)GetValue(GridSplitterHeightProperty); } - set { SetValue(GridSplitterHeightProperty, value); } - } - - #endregion - - internal void _ExecuteContentActivateCommand(LayoutContent content) - { - content.IsActive = true; - } - - #region DocumentPaneMenuItemHeaderTemplate - - /// - /// DocumentPaneMenuItemHeaderTemplate Dependency Property - /// - public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateProperty = - DependencyProperty.Register("DocumentPaneMenuItemHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null, - new PropertyChangedCallback(OnDocumentPaneMenuItemHeaderTemplateChanged), - new CoerceValueCallback(CoerceDocumentPaneMenuItemHeaderTemplateValue))); - - /// - /// Gets or sets the DocumentPaneMenuItemHeaderTemplate property. This dependency property - /// indicates the header template to use while creating menu items for the document panes. - /// - public DataTemplate DocumentPaneMenuItemHeaderTemplate - { - get { return (DataTemplate)GetValue(DocumentPaneMenuItemHeaderTemplateProperty); } - set { SetValue(DocumentPaneMenuItemHeaderTemplateProperty, value); } - } - - /// - /// Handles changes to the DocumentPaneMenuItemHeaderTemplate property. - /// - private static void OnDocumentPaneMenuItemHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentPaneMenuItemHeaderTemplateChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplate property. - /// - protected virtual void OnDocumentPaneMenuItemHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) - { - } - - /// - /// Coerces the DocumentPaneMenuItemHeaderTemplate value. - /// - private static object CoerceDocumentPaneMenuItemHeaderTemplateValue(DependencyObject d, object value) - { - if (value != null && - d.GetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty) != null) - return null; - if (value == null) - return d.GetValue(DocumentHeaderTemplateProperty); - - return value; - } - - #endregion - - #region DocumentPaneMenuItemHeaderTemplateSelector - - /// - /// DocumentPaneMenuItemHeaderTemplateSelector Dependency Property - /// - public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateSelectorProperty = - DependencyProperty.Register("DocumentPaneMenuItemHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null, - new PropertyChangedCallback(OnDocumentPaneMenuItemHeaderTemplateSelectorChanged), - new CoerceValueCallback(CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue))); - - /// - /// Gets or sets the DocumentPaneMenuItemHeaderTemplateSelector property. This dependency property - /// indicates the data template selector to use for the menu items show when user select the DocumentPane document switch context menu. - /// - public DataTemplateSelector DocumentPaneMenuItemHeaderTemplateSelector - { - get { return (DataTemplateSelector)GetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty); } - set { SetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty, value); } - } - - /// - /// Handles changes to the DocumentPaneMenuItemHeaderTemplateSelector property. - /// - private static void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplateSelector property. - /// - protected virtual void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue != null && - DocumentPaneMenuItemHeaderTemplate != null) - DocumentPaneMenuItemHeaderTemplate = null; - - } - - /// - /// Coerces the DocumentPaneMenuItemHeaderTemplateSelector value. - /// - private static object CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue(DependencyObject d, object value) - { - return value; - } - - #endregion - - #region IconContentTemplate - - /// - /// IconContentTemplate Dependency Property - /// - public static readonly DependencyProperty IconContentTemplateProperty = - DependencyProperty.Register("IconContentTemplate", typeof(DataTemplate), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplate)null)); - - /// - /// Gets or sets the IconContentTemplate property. This dependency property - /// indicates the data template to use while extracting the icon from model. - /// - public DataTemplate IconContentTemplate - { - get { return (DataTemplate)GetValue(IconContentTemplateProperty); } - set { SetValue(IconContentTemplateProperty, value); } - } - - #endregion - - #region IconContentTemplateSelector - - /// - /// IconContentTemplateSelector Dependency Property - /// - public static readonly DependencyProperty IconContentTemplateSelectorProperty = - DependencyProperty.Register("IconContentTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((DataTemplateSelector)null)); - - /// - /// Gets or sets the IconContentTemplateSelector property. This dependency property - /// indicates data template selector to use while selecting the datatamplate for content icons. - /// - public DataTemplateSelector IconContentTemplateSelector - { - get { return (DataTemplateSelector)GetValue(IconContentTemplateSelectorProperty); } - set { SetValue(IconContentTemplateSelectorProperty, value); } - } - - #endregion - - #region LayoutItems - - List _layoutItems = new List(); - - bool _suspendLayoutItemCreation = false; - - void DetachLayoutItems() - { - if (Layout != null) - { - _layoutItems.ForEach(i => i.Detach()); - _layoutItems.Clear(); - Layout.ElementAdded -= new EventHandler(Layout_ElementAdded); - Layout.ElementRemoved -= new EventHandler(Layout_ElementRemoved); - } - } - - void Layout_ElementRemoved(object sender, LayoutElementEventArgs e) - { - if (_suspendLayoutItemCreation) - return; - - CollectLayoutItemsDeleted(); - } - - void Layout_ElementAdded(object sender, LayoutElementEventArgs e) - { - if (_suspendLayoutItemCreation) - return; - - foreach (var content in Layout.Descendents().OfType()) - { - if (content is LayoutDocument) - CreateDocumentLayoutItem(content as LayoutDocument); - else //if (content is LayoutAnchorable) - CreateAnchorableLayoutItem(content as LayoutAnchorable); - } - - CollectLayoutItemsDeleted(); - } - - - DispatcherOperation _collectLayoutItemsOperations = null; - void CollectLayoutItemsDeleted() - { - if (_collectLayoutItemsOperations != null) - return; - _collectLayoutItemsOperations = Dispatcher.BeginInvoke(new Action(() => - { - _collectLayoutItemsOperations = null; - foreach (var itemToRemove in _layoutItems.Where(item => item.LayoutElement.Root != Layout).ToArray()) - { - - if (itemToRemove != null && - itemToRemove.Model != null && - itemToRemove.Model is UIElement) - { - //((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(itemToRemove.Model as UIElement); - } - - itemToRemove.Detach(); - _layoutItems.Remove(itemToRemove); - - } - })); - } - - - void AttachLayoutItems() - { - if (Layout != null) - { - foreach (var document in Layout.Descendents().OfType().ToArray()) - { - CreateDocumentLayoutItem(document); - //var documentItem = new LayoutDocumentItem(); - //documentItem.Attach(document); - //ApplyStyleToLayoutItem(documentItem); - //_layoutItems.Add(documentItem); - } - foreach (var anchorable in Layout.Descendents().OfType().ToArray()) - { - CreateAnchorableLayoutItem(anchorable); - //var anchorableItem = new LayoutAnchorableItem(); - //anchorableItem.Attach(anchorable); - //ApplyStyleToLayoutItem(anchorableItem); - //_layoutItems.Add(anchorableItem); - } - - Layout.ElementAdded += new EventHandler(Layout_ElementAdded); - Layout.ElementRemoved += new EventHandler(Layout_ElementRemoved); - } - } - - void ApplyStyleToLayoutItem(LayoutItem layoutItem) - { - layoutItem._ClearDefaultBindings(); - if (LayoutItemContainerStyle != null) - layoutItem.Style = LayoutItemContainerStyle; - else if (LayoutItemContainerStyleSelector != null) - layoutItem.Style = LayoutItemContainerStyleSelector.SelectStyle(layoutItem.Model, layoutItem); - layoutItem._SetDefaultBindings(); - } - - void CreateAnchorableLayoutItem(LayoutAnchorable contentToAttach) - { - if (_layoutItems.Any(item => item.LayoutElement == contentToAttach)) - return; - - var layoutItem = new LayoutAnchorableItem(); - layoutItem.Attach(contentToAttach); - ApplyStyleToLayoutItem(layoutItem); - _layoutItems.Add(layoutItem); - - if (contentToAttach != null && - contentToAttach.Content != null && - contentToAttach.Content is UIElement) - { - InternalAddLogicalChild(contentToAttach.Content); - } - - } - - void CreateDocumentLayoutItem(LayoutDocument contentToAttach) - { - if (_layoutItems.Any(item => item.LayoutElement == contentToAttach)) - return; - - var layoutItem = new LayoutDocumentItem(); - layoutItem.Attach(contentToAttach); - ApplyStyleToLayoutItem(layoutItem); - _layoutItems.Add(layoutItem); - - if (contentToAttach != null && - contentToAttach.Content != null && - contentToAttach.Content is UIElement) - { - InternalAddLogicalChild(contentToAttach.Content); - } - - } - - #region LayoutItemContainerStyle - - /// - /// LayoutItemContainerStyle Dependency Property - /// - public static readonly DependencyProperty LayoutItemContainerStyleProperty = - DependencyProperty.Register("LayoutItemContainerStyle", typeof(Style), typeof(DockingManager), - new FrameworkPropertyMetadata((Style)null, - new PropertyChangedCallback(OnLayoutItemContainerStyleChanged))); - - /// - /// Gets or sets the LayoutItemContainerStyle property. This dependency property - /// indicates the style to apply to LayoutDocumentItem objects. A LayoutDocumentItem object is created when a new LayoutDocument is created inside the current Layout. - /// - public Style LayoutItemContainerStyle - { - get { return (Style)GetValue(LayoutItemContainerStyleProperty); } - set { SetValue(LayoutItemContainerStyleProperty, value); } - } - - /// - /// Handles changes to the LayoutItemContainerStyle property. - /// - private static void OnLayoutItemContainerStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutItemContainerStyleChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyle property. - /// - protected virtual void OnLayoutItemContainerStyleChanged(DependencyPropertyChangedEventArgs e) - { - AttachLayoutItems(); - } - - #endregion - - #region LayoutItemContainerStyleSelector - - /// - /// LayoutItemContainerStyleSelector Dependency Property - /// - public static readonly DependencyProperty LayoutItemContainerStyleSelectorProperty = - DependencyProperty.Register("LayoutItemContainerStyleSelector", typeof(StyleSelector), typeof(DockingManager), - new FrameworkPropertyMetadata((StyleSelector)null, - new PropertyChangedCallback(OnLayoutItemContainerStyleSelectorChanged))); - - /// - /// Gets or sets the LayoutItemContainerStyleSelector property. This dependency property - /// indicates style selector of the LayoutDocumentItemStyle. - /// - public StyleSelector LayoutItemContainerStyleSelector - { - get { return (StyleSelector)GetValue(LayoutItemContainerStyleSelectorProperty); } - set { SetValue(LayoutItemContainerStyleSelectorProperty, value); } - } - - /// - /// Handles changes to the LayoutItemContainerStyleSelector property. - /// - private static void OnLayoutItemContainerStyleSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DockingManager)d).OnLayoutItemContainerStyleSelectorChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyleSelector property. - /// - protected virtual void OnLayoutItemContainerStyleSelectorChanged(DependencyPropertyChangedEventArgs e) - { - AttachLayoutItems(); - } - - #endregion - - /// - /// Return the LayoutItem wrapper for the content passed as argument - /// - /// LayoutContent to search - /// Either a LayoutAnchorableItem or LayoutDocumentItem which contains the LayoutContent passed as argument - public LayoutItem GetLayoutItemFromModel(LayoutContent content) - { - return _layoutItems.FirstOrDefault(item => item.LayoutElement == content); - } - #endregion - - #region NavigatorWindow - NavigatorWindow _navigatorWindow = null; - - void ShowNavigatorWindow() - { - if (_navigatorWindow == null) - { - _navigatorWindow = new NavigatorWindow(this) - { - Owner = Window.GetWindow(this), - WindowStartupLocation = WindowStartupLocation.CenterOwner - }; - } - - _navigatorWindow.ShowDialog(); - _navigatorWindow = null; - - Trace.WriteLine( "ShowNavigatorWindow()" ); - } - - bool IsNavigatorWindowActive - { - get { return _navigatorWindow != null; } - } - - - protected override void OnPreviewKeyDown(KeyEventArgs e) - { - Trace.WriteLine( string.Format( "OnPreviewKeyDown({0})", e.Key ) ); - if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) - { - if (e.IsDown && e.Key == Key.Tab) - { - if (!IsNavigatorWindowActive) - { - ShowNavigatorWindow(); - e.Handled = true; - } - } - } - - base.OnPreviewKeyDown(e); - } - - #endregion - - #region ShowSystemMenu - - /// - /// ShowSystemMenu Dependency Property - /// - public static readonly DependencyProperty ShowSystemMenuProperty = - DependencyProperty.Register("ShowSystemMenu", typeof(bool), typeof(DockingManager), - new FrameworkPropertyMetadata((bool)true)); - - /// - /// Gets or sets the ShowSystemMenu property. This dependency property - /// indicates if floating windows should show the system menu when a custom context menu is not defined. - /// - public bool ShowSystemMenu - { - get { return (bool)GetValue(ShowSystemMenuProperty); } - set { SetValue(ShowSystemMenuProperty, value); } - } - - #endregion - - #region AllowMixedOrientation - - /// - /// AllowMixedOrientation Dependency Property - /// - public static readonly DependencyProperty AllowMixedOrientationProperty = - DependencyProperty.Register("AllowMixedOrientation", typeof(bool), typeof(DockingManager), - new FrameworkPropertyMetadata((bool)false)); - - /// - /// Gets or sets the AllowMixedOrientation property. This dependency property - /// indicates if the manager should allow mixed orientation for document panes. - /// - public bool AllowMixedOrientation - { - get { return (bool)GetValue(AllowMixedOrientationProperty); } - set { SetValue(AllowMixedOrientationProperty, value); } - } - - #endregion - - - } + if (((FrameworkElement)element).Parent != null) + { + (((FrameworkElement)element).Parent as DockingManager).InternalRemoveLogicalChild(element); + } + + _logicalChildren.Add(new WeakReference(element)); + AddLogicalChild(element); + } + + internal void InternalRemoveLogicalChild(object element) + { + //System.Diagnostics.Trace.WriteLine("[{0}]InternalRemoveLogicalChild({1})", this, element); + + var wrToRemove = _logicalChildren.FirstOrDefault(ch => ch.GetValueOrDefault() == element); + if (wrToRemove != null) + _logicalChildren.Remove(wrToRemove); + RemoveLogicalChild(element); + } + + void ClearLogicalChildrenList() + { + foreach (var child in _logicalChildren.Select(ch => ch.GetValueOrDefault()).ToArray()) + RemoveLogicalChild(child); + _logicalChildren.Clear(); + } + + #endregion + + #region AutoHide window + internal void ShowAutoHideWindow(LayoutAnchorControl anchor) + { + _autoHideWindowManager.ShowAutoHideWindow(anchor); + //if (_autohideArea == null) + // return; + + //if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) + // return; + + //Trace.WriteLine("ShowAutoHideWindow()"); + + //_currentAutohiddenAnchor = new WeakReference(anchor); + + //HideAutoHideWindow(anchor); + + //SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); + //AutoHideWindow.Show(); + } + + internal void HideAutoHideWindow(LayoutAnchorControl anchor) + { + _autoHideWindowManager.HideAutoWindow(anchor); + } + + + void SetupAutoHideWindow() + { + _autohideArea = GetTemplateChild("PART_AutoHideArea") as FrameworkElement; + + if (_autoHideWindowManager != null) + _autoHideWindowManager.HideAutoWindow(); + else + _autoHideWindowManager = new AutoHideWindowManager(this); + + if (AutoHideWindow != null) + AutoHideWindow.Dispose(); + + SetAutoHideWindow(new LayoutAutoHideWindowControl()); + } + + AutoHideWindowManager _autoHideWindowManager; + + FrameworkElement _autohideArea; + internal FrameworkElement GetAutoHideAreaElement() + { + return _autohideArea; + } + + #region AutoHideWindow + + /// + /// AutoHideWindow Read-Only Dependency Property + /// + private static readonly DependencyPropertyKey AutoHideWindowPropertyKey + = DependencyProperty.RegisterReadOnly("AutoHideWindow", typeof(LayoutAutoHideWindowControl), typeof(DockingManager), + new FrameworkPropertyMetadata((LayoutAutoHideWindowControl)null, + new PropertyChangedCallback(OnAutoHideWindowChanged))); + + public static readonly DependencyProperty AutoHideWindowProperty + = AutoHideWindowPropertyKey.DependencyProperty; + + /// + /// Gets the AutoHideWindow property. This dependency property + /// indicates the currently shown autohide window. + /// + public LayoutAutoHideWindowControl AutoHideWindow + { + get { return (LayoutAutoHideWindowControl)GetValue(AutoHideWindowProperty); } + } + + /// + /// Provides a secure method for setting the AutoHideWindow property. + /// This dependency property indicates the currently shown autohide window. + /// + /// The new value for the property. + protected void SetAutoHideWindow(LayoutAutoHideWindowControl value) + { + SetValue(AutoHideWindowPropertyKey, value); + } + + /// + /// Handles changes to the AutoHideWindow property. + /// + private static void OnAutoHideWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAutoHideWindowChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AutoHideWindow property. + /// + protected virtual void OnAutoHideWindowChanged(DependencyPropertyChangedEventArgs e) + { + if (e.OldValue != null) + InternalRemoveLogicalChild(e.OldValue); + if (e.NewValue != null) + InternalAddLogicalChild(e.NewValue); + + } + + #endregion + + + + #endregion + // #region AutoHide window + //WeakReference _currentAutohiddenAnchor = null; + //internal void ShowAutoHideWindow(LayoutAnchorControl anchor) + //{ + // if (_autohideArea == null) + // return; + + // if (AutoHideWindow != null && AutoHideWindow.Model == anchor.Model) + // return; + + // Trace.WriteLine("ShowAutoHideWindow()"); + + // _currentAutohiddenAnchor = new WeakReference(anchor); + + // HideAutoHideWindow(anchor); + + // SetAutoHideWindow(new LayoutAutoHideWindowControl(anchor)); + //} + + //internal void HideAutoHideWindow(LayoutAnchorControl anchor) + //{ + // if (AutoHideWindow != null) + // { + // if (anchor == _currentAutohiddenAnchor.GetValueOrDefault()) + // { + // Trace.WriteLine("AutoHideWindow()"); + // AutoHideWindow.Dispose(); + // SetAutoHideWindow(null); + // } + // } + //} + + //FrameworkElement _autohideArea; + //internal FrameworkElement GetAutoHideAreaElement() + //{ + // return _autohideArea; + //} + + //void SetupAutoHideArea() + //{ + // _autohideArea = GetTemplateChild("PART_AutoHideArea") as FrameworkElement; + //} + + // #region AutoHideWindow + + ///// + ///// AutoHideWindow Read-Only Dependency Property + ///// + //private static readonly DependencyPropertyKey AutoHideWindowPropertyKey + // = DependencyProperty.RegisterReadOnly("AutoHideWindow", typeof(LayoutAutoHideWindowControl), typeof(DockingManager), + // new FrameworkPropertyMetadata((LayoutAutoHideWindowControl)null, + // new PropertyChangedCallback(OnAutoHideWindowChanged))); + + //public static readonly DependencyProperty AutoHideWindowProperty + // = AutoHideWindowPropertyKey.DependencyProperty; + + ///// + ///// Gets the AutoHideWindow property. This dependency property + ///// indicates the currently shown autohide window. + ///// + //public LayoutAutoHideWindowControl AutoHideWindow + //{ + // get { return (LayoutAutoHideWindowControl)GetValue(AutoHideWindowProperty); } + //} + + ///// + ///// Provides a secure method for setting the AutoHideWindow property. + ///// This dependency property indicates the currently shown autohide window. + ///// + ///// The new value for the property. + //protected void SetAutoHideWindow(LayoutAutoHideWindowControl value) + //{ + // SetValue(AutoHideWindowPropertyKey, value); + //} + + ///// + ///// Handles changes to the AutoHideWindow property. + ///// + //private static void OnAutoHideWindowChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + //{ + // ((DockingManager)d).OnAutoHideWindowChanged(e); + //} + + ///// + ///// Provides derived classes an opportunity to handle changes to the AutoHideWindow property. + ///// + //protected virtual void OnAutoHideWindowChanged(DependencyPropertyChangedEventArgs e) + //{ + // if (e.OldValue != null) + // ((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(e.OldValue); + // if (e.NewValue != null) + // ((ILogicalChildrenContainer)this).InternalAddLogicalChild(e.NewValue); + //} + + // #endregion + + + + // #endregion + + #region Floating Windows + List _fwList = new List(); + + internal void StartDraggingFloatingWindowForContent(LayoutContent contentModel, bool startDrag = true) + { + if (!contentModel.CanFloat) + return; + var contentModelAsAnchorable = contentModel as LayoutAnchorable; + if (contentModelAsAnchorable != null && + contentModelAsAnchorable.IsAutoHidden) + contentModelAsAnchorable.ToggleAutoHide(); + + var parentPane = contentModel.Parent as ILayoutPane; + var parentPaneAsPositionableElement = contentModel.Parent as ILayoutPositionableElement; + var parentPaneAsWithActualSize = contentModel.Parent as ILayoutPositionableElementWithActualSize; + var contentModelParentChildrenIndex = parentPane.Children.ToList().IndexOf(contentModel); + + if (contentModel.FindParent() == null) + { + ((ILayoutPreviousContainer)contentModel).PreviousContainer = parentPane; + contentModel.PreviousContainerIndex = contentModelParentChildrenIndex; + } + + parentPane.RemoveChildAt(contentModelParentChildrenIndex); + + double fwWidth = contentModel.FloatingWidth; + double fwHeight = contentModel.FloatingHeight; + + if (fwWidth == 0.0) + fwWidth = parentPaneAsPositionableElement.FloatingWidth; + if (fwHeight == 0.0) + fwHeight = parentPaneAsPositionableElement.FloatingHeight; + + if (fwWidth == 0.0) + fwWidth = parentPaneAsWithActualSize.ActualWidth; + if (fwHeight == 0.0) + fwHeight = parentPaneAsWithActualSize.ActualHeight; + + LayoutFloatingWindow fw; + LayoutFloatingWindowControl fwc; + if (contentModel is LayoutAnchorable) + { + var anchorableContent = contentModel as LayoutAnchorable; + fw = new LayoutAnchorableFloatingWindow() + { + RootPanel = new LayoutAnchorablePaneGroup( + new LayoutAnchorablePane(anchorableContent) + { + 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); + + fwc = new LayoutAnchorableFloatingWindowControl( + fw as LayoutAnchorableFloatingWindow) + { + Width = fwWidth, + Height = fwHeight, + Left = contentModel.FloatingLeft, + Top = contentModel.FloatingTop + }; + } + else + { + var anchorableDocument = contentModel as LayoutDocument; + fw = new LayoutDocumentFloatingWindow() + { + RootDocument = anchorableDocument + }; + + Layout.FloatingWindows.Add(fw); + + fwc = new LayoutDocumentFloatingWindowControl( + fw as LayoutDocumentFloatingWindow) + { + Width = fwWidth, + Height = fwHeight, + Left = contentModel.FloatingLeft, + Top = contentModel.FloatingTop + }; + } + + + //fwc.Owner = Window.GetWindow(this); + //fwc.SetParentToMainWindowOf(this); + + + _fwList.Add(fwc); + + Layout.CollectGarbage(); + + UpdateLayout(); + + Dispatcher.BeginInvoke(new Action(() => + { + if (startDrag) + fwc.AttachDrag(); + fwc.Show(); + }), DispatcherPriority.Send); + } + + internal void StartDraggingFloatingWindowForPane(LayoutAnchorablePane paneModel) + { + if (paneModel.Children.Any(c => !c.CanFloat)) + return; + var paneAsPositionableElement = paneModel as ILayoutPositionableElement; + var paneAsWithActualSize = paneModel as ILayoutPositionableElementWithActualSize; + + double fwWidth = paneAsPositionableElement.FloatingWidth; + double fwHeight = paneAsPositionableElement.FloatingHeight; + double fwLeft = paneAsPositionableElement.FloatingLeft; + double fwTop = paneAsPositionableElement.FloatingTop; + + + + if (fwWidth == 0.0) + fwWidth = paneAsWithActualSize.ActualWidth; + if (fwHeight == 0.0) + fwHeight = paneAsWithActualSize.ActualHeight; + + var destPane = new LayoutAnchorablePane() + { + DockWidth = paneAsPositionableElement.DockWidth, + DockHeight = paneAsPositionableElement.DockHeight, + DockMinHeight = paneAsPositionableElement.DockMinHeight, + DockMinWidth = paneAsPositionableElement.DockMinWidth, + FloatingLeft = paneAsPositionableElement.FloatingLeft, + FloatingTop = paneAsPositionableElement.FloatingTop, + FloatingWidth = paneAsPositionableElement.FloatingWidth, + FloatingHeight = paneAsPositionableElement.FloatingHeight, + }; + + bool savePreviousContainer = paneModel.FindParent() == null; + int currentSelectedContentIndex = paneModel.SelectedContentIndex; + while (paneModel.Children.Count > 0) + { + var contentModel = paneModel.Children[paneModel.Children.Count - 1] as LayoutAnchorable; + + if (savePreviousContainer) + { + var contentModelAsPreviousContainer = contentModel as ILayoutPreviousContainer; + contentModelAsPreviousContainer.PreviousContainer = paneModel; + contentModel.PreviousContainerIndex = paneModel.Children.Count - 1; + } + + paneModel.RemoveChildAt(paneModel.Children.Count - 1); + destPane.Children.Insert(0, contentModel); + } + + if (destPane.Children.Count > 0) + { + destPane.SelectedContentIndex = currentSelectedContentIndex; + } + + + LayoutFloatingWindow fw; + LayoutFloatingWindowControl fwc; + fw = new LayoutAnchorableFloatingWindow() + { + RootPanel = new LayoutAnchorablePaneGroup( + destPane) + { + DockHeight = destPane.DockHeight, + DockWidth = destPane.DockWidth, + DockMinHeight = destPane.DockMinHeight, + DockMinWidth = destPane.DockMinWidth, + } + }; + + Layout.FloatingWindows.Add(fw); + + fwc = new LayoutAnchorableFloatingWindowControl( + fw as LayoutAnchorableFloatingWindow) + { + Width = fwWidth, + Height = fwHeight + }; + + + + //fwc.Owner = Window.GetWindow(this); + //fwc.SetParentToMainWindowOf(this); + + + _fwList.Add(fwc); + + Layout.CollectGarbage(); + + InvalidateArrange(); + + fwc.AttachDrag(); + fwc.Show(); + + } + + internal IEnumerable GetFloatingWindowsByZOrder() + { + var parentWindow = Window.GetWindow(this); + + if (parentWindow == null) + yield break; + + IntPtr windowParentHanlde = new WindowInteropHelper(parentWindow).Handle; + + IntPtr currentHandle = Win32Helper.GetWindow(windowParentHanlde, (uint)Win32Helper.GetWindow_Cmd.GW_HWNDFIRST); + while (currentHandle != IntPtr.Zero) + { + LayoutFloatingWindowControl ctrl = _fwList.FirstOrDefault(fw => new WindowInteropHelper(fw).Handle == currentHandle); + if (ctrl != null && ctrl.Model.Root.Manager == this) + yield return ctrl; + + currentHandle = Win32Helper.GetWindow(currentHandle, (uint)Win32Helper.GetWindow_Cmd.GW_HWNDNEXT); + } + } + + internal void RemoveFloatingWindow(LayoutFloatingWindowControl floatingWindow) + { + _fwList.Remove(floatingWindow); + } + + public IEnumerable FloatingWindows + { + get { return _fwList; } + } + #endregion + + #region OverlayWindow + + bool IOverlayWindowHost.HitTest(Point dragPoint) + { + if (!this.IsVisible) return false; + Rect detectionRect = new Rect(this.PointToScreenDPIWithoutFlowDirection(new Point()), this.TransformActualSizeToAncestor()); + return detectionRect.Contains(dragPoint); + } + + DockingManager IOverlayWindowHost.Manager + { + get { return this; } + } + + 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; + } + + void DestroyOverlayWindow() + { + if (_overlayWindow != null) + { + _overlayWindow.Close(); + _overlayWindow = null; + } + } + + IOverlayWindow IOverlayWindowHost.ShowOverlayWindow(LayoutFloatingWindowControl draggingWindow) + { + //Trace.WriteLine("ShowOverlayWindow"); + CreateOverlayWindow(); + if (draggingWindow.Model.Root.ActiveContent.CanDock) + { + _overlayWindow.Owner = draggingWindow; + _overlayWindow.EnableDropTargets(); + _overlayWindow.Show(); + } + return _overlayWindow; + } + + void IOverlayWindowHost.HideOverlayWindow() + { + //Trace.WriteLine("HideOverlayWindow"); + _areas = null; + _overlayWindow.Owner = null; + _overlayWindow.HideDropTargets(); + } + + List _areas = null; + + IEnumerable IOverlayWindowHost.GetDropAreas(LayoutFloatingWindowControl draggingWindow) + { + if (_areas != null) + return _areas; + + bool isDraggingDocuments = draggingWindow.Model is LayoutDocumentFloatingWindow; + + _areas = new List(); + + if (!isDraggingDocuments) + { + _areas.Add(new DropArea( + this, + DropAreaType.DockingManager)); + + foreach (var areaHost in this.FindVisualChildren()) + { + if (areaHost.Model.Descendents().Any()) + { + _areas.Add(new DropArea( + areaHost, + DropAreaType.AnchorablePane)); + } + } + } + + foreach (var areaHost in this.FindVisualChildren()) + { + _areas.Add(new DropArea( + areaHost, + DropAreaType.DocumentPane)); + } + + foreach (var areaHost in this.FindVisualChildren()) + { + var documentGroupModel = areaHost.Model as LayoutDocumentPaneGroup; + if (documentGroupModel.Children.Where(c => c.IsVisible).Count() == 0) + { + _areas.Add(new DropArea( + areaHost, + DropAreaType.DocumentPaneGroup)); + } + } + + return _areas; + } + + protected override Size ArrangeOverride(Size arrangeBounds) + { + _areas = null; + return base.ArrangeOverride(arrangeBounds); + } + + #endregion + + #region LayoutDocument & LayoutAnchorable Templates + + #region LayoutItemTemplate + + /// + /// LayoutItemTemplate Dependency Property + /// + public static readonly DependencyProperty LayoutItemTemplateProperty = + DependencyProperty.Register("LayoutItemTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnLayoutItemTemplateChanged))); + + /// + /// Gets or sets the AnchorableTemplate property. This dependency property + /// indicates the template to use to render anchorable and document contents. + /// + public DataTemplate LayoutItemTemplate + { + get { return (DataTemplate)GetValue(LayoutItemTemplateProperty); } + set { SetValue(LayoutItemTemplateProperty, value); } + } + + /// + /// Handles changes to the AnchorableTemplate property. + /// + private static void OnLayoutItemTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutItemTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorableTemplate property. + /// + protected virtual void OnLayoutItemTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + #region LayoutItemTemplateSelector + + /// + /// LayoutItemTemplateSelector Dependency Property + /// + public static readonly DependencyProperty LayoutItemTemplateSelectorProperty = + DependencyProperty.Register("LayoutItemTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnLayoutItemTemplateSelectorChanged))); + + /// + /// Gets or sets the LayoutItemTemplateSelector property. This dependency property + /// indicates selector object to use for anchorable templates. + /// + public DataTemplateSelector LayoutItemTemplateSelector + { + get { return (DataTemplateSelector)GetValue(LayoutItemTemplateSelectorProperty); } + set { SetValue(LayoutItemTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the LayoutItemTemplateSelector property. + /// + private static void OnLayoutItemTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutItemTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the LayoutItemTemplateSelector property. + /// + protected virtual void OnLayoutItemTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + } + + #endregion + + + #endregion + + #region DocumentsSource + + /// + /// DocumentsSource Dependency Property + /// + public static readonly DependencyProperty DocumentsSourceProperty = + DependencyProperty.Register("DocumentsSource", typeof(IEnumerable), typeof(DockingManager), + new FrameworkPropertyMetadata((IEnumerable)null, + new PropertyChangedCallback(OnDocumentsSourceChanged))); + + /// + /// Gets or sets the DocumentsSource property. This dependency property + /// indicates the source collection of documents. + /// + public IEnumerable DocumentsSource + { + get { return (IEnumerable)GetValue(DocumentsSourceProperty); } + set { SetValue(DocumentsSourceProperty, value); } + } + + /// + /// Handles changes to the DocumentsSource property. + /// + private static void OnDocumentsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentsSourceChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentsSource property. + /// + protected virtual void OnDocumentsSourceChanged(DependencyPropertyChangedEventArgs e) + { + DetachDocumentsSource(Layout, e.OldValue as IEnumerable); + AttachDocumentsSource(Layout, e.NewValue as IEnumerable); + } + + + void AttachDocumentsSource(LayoutRoot layout, IEnumerable documentsSource) + { + if (documentsSource == null) + return; + + if (layout == null) + return; + + //if (layout.Descendents().OfType().Any()) + // throw new InvalidOperationException("Unable to set the DocumentsSource property if LayoutDocument objects are already present in the model"); + var documentsImported = layout.Descendents().OfType().Select(d => d.Content).ToArray(); + var documents = documentsSource as IEnumerable; + var listOfDocumentsToImport = new List(documents.OfType()); + + foreach (var document in listOfDocumentsToImport.ToArray()) + { + if (documentsImported.Contains(document)) + listOfDocumentsToImport.Remove(document); + } + + + LayoutDocumentPane documentPane = null; + if (layout.LastFocusedDocument != null) + { + documentPane = layout.LastFocusedDocument.Parent as LayoutDocumentPane; + } + + if (documentPane == null) + { + documentPane = layout.Descendents().OfType().FirstOrDefault(); + } + + //if (documentPane == null) + // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + _suspendLayoutItemCreation = true; + foreach (var documentContentToImport in listOfDocumentsToImport) + { + + //documentPane.Children.Add(new LayoutDocument() { Content = documentToImport }); + + var documentToImport = new LayoutDocument() + { + Content = documentContentToImport + }; + + bool added = false; + if (LayoutUpdateStrategy != null) + { + added = LayoutUpdateStrategy.BeforeInsertDocument(layout, documentToImport, documentPane); + } + + if (!added) + { + if (documentPane == null) + throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + documentPane.Children.Add(documentToImport); + added = true; + } + + if (LayoutUpdateStrategy != null) + LayoutUpdateStrategy.AfterInsertDocument(layout, documentToImport); + + + CreateDocumentLayoutItem(documentToImport); + + } + _suspendLayoutItemCreation = true; + + + var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; + if (documentsSourceAsNotifier != null) + documentsSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(documentsSourceElementsChanged); + } + + internal bool SuspendDocumentsSourceBinding = false; + + void documentsSourceElementsChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (Layout == null) + return; + + //When deserializing documents are created automatically by the deserializer + if (SuspendDocumentsSourceBinding) + return; + + //handle remove + if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) + { + if (e.OldItems != null) + { + var documentsToRemove = Layout.Descendents().OfType().Where(d => e.OldItems.Contains(d.Content)).ToArray(); + foreach (var documentToRemove in documentsToRemove) + { + (documentToRemove.Parent as ILayoutContainer).RemoveChild( + documentToRemove); + } + } + } + + //handle add + if (e.NewItems != null && + (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace)) + { + if (e.NewItems != null) + { + LayoutDocumentPane documentPane = null; + if (Layout.LastFocusedDocument != null) + { + documentPane = Layout.LastFocusedDocument.Parent as LayoutDocumentPane; + } + + if (documentPane == null) + { + documentPane = Layout.Descendents().OfType().FirstOrDefault(); + } + + //if (documentPane == null) + // throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + _suspendLayoutItemCreation = true; + + foreach (var documentContentToImport in e.NewItems) + { + var documentToImport = new LayoutDocument() + { + Content = documentContentToImport + }; + + bool added = false; + if (LayoutUpdateStrategy != null) + { + added = LayoutUpdateStrategy.BeforeInsertDocument(Layout, documentToImport, documentPane); + } + + if (!added) + { + if (documentPane == null) + throw new InvalidOperationException("Layout must contains at least one LayoutDocumentPane in order to host documents"); + + documentPane.Children.Add(documentToImport); + added = true; + } + + if (LayoutUpdateStrategy != null) + { + LayoutUpdateStrategy.AfterInsertDocument(Layout, documentToImport); + } + + + var root = documentToImport.Root; + + if (root != null && root.Manager == this) + { + CreateDocumentLayoutItem(documentToImport); + } + } + _suspendLayoutItemCreation = false; + } + } + + if (e.Action == NotifyCollectionChangedAction.Reset) + { + //NOTE: I'm going to clear every document present in layout but + //some documents may have been added directly to the layout, for now I clear them too + var documentsToRemove = Layout.Descendents().OfType().ToArray(); + foreach (var documentToRemove in documentsToRemove) + { + (documentToRemove.Parent as ILayoutContainer).RemoveChild( + documentToRemove); + } + } + + if (Layout != null) + { + Layout.CollectGarbage(); + } + } + + void DetachDocumentsSource(LayoutRoot layout, IEnumerable documentsSource) + { + if (documentsSource == null) + return; + + if (layout == null) + return; + + var documentsToRemove = layout.Descendents().OfType() + .Where(d => documentsSource.Contains(d.Content)).ToArray(); + + foreach (var documentToRemove in documentsToRemove) + { + (documentToRemove.Parent as ILayoutContainer).RemoveChild( + documentToRemove); + } + + var documentsSourceAsNotifier = documentsSource as INotifyCollectionChanged; + if (documentsSourceAsNotifier != null) + documentsSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler(documentsSourceElementsChanged); + } + + + #endregion + + #region DocumentCloseCommand + + internal void _ExecuteCloseCommand(LayoutDocument document) + { + if (DocumentClosing != null) + { + var evargs = new DocumentClosingEventArgs(document); + DocumentClosing(this, evargs); + if (evargs.Cancel) + return; + } + + if (!document.TestCanClose()) + return; + + document.Close(); + + if (DocumentClosed != null) + { + var evargs = new DocumentClosedEventArgs(document); + DocumentClosed(this, evargs); + } + } + + /// + /// Event fired when a document is about to be closed + /// + /// Subscribers have the opportuniy to cancel the operation. + public event EventHandler DocumentClosing; + + /// + /// Event fired after a document is closed + /// + public event EventHandler DocumentClosed; + + + + #endregion + + internal void _ExecuteCloseAllButThisCommand(LayoutContent contentSelected) + { + foreach (var contentToClose in Layout.Descendents().OfType().Where(d => d != contentSelected && (d.Parent is LayoutDocumentPane || d.Parent is LayoutDocumentFloatingWindow)).ToArray()) + { + if (!contentToClose.CanClose) + continue; + + var layoutItem = GetLayoutItemFromModel(contentToClose); + if (layoutItem.CloseCommand != null) + { + if (layoutItem.CloseCommand.CanExecute(null)) + layoutItem.CloseCommand.Execute(null); + } + else + { + if (contentToClose is LayoutDocument) + _ExecuteCloseCommand(contentToClose as LayoutDocument); + else if (contentToClose is LayoutAnchorable) + _ExecuteCloseCommand(contentToClose as LayoutAnchorable); + } + } + } + + #region DocumentContextMenu + + /// + /// DocumentContextMenu Dependency Property + /// + public static readonly DependencyProperty DocumentContextMenuProperty = + DependencyProperty.Register("DocumentContextMenu", typeof(ContextMenu), typeof(DockingManager), + new FrameworkPropertyMetadata((ContextMenu)null)); + + /// + /// Gets or sets the DocumentContextMenu property. This dependency property + /// indicates context menu to show for documents. + /// + public ContextMenu DocumentContextMenu + { + get { return (ContextMenu)GetValue(DocumentContextMenuProperty); } + set { SetValue(DocumentContextMenuProperty, value); } + } + + #endregion + + #region AnchorablesSource + + /// + /// AnchorablesSource Dependency Property + /// + public static readonly DependencyProperty AnchorablesSourceProperty = + DependencyProperty.Register("AnchorablesSource", typeof(IEnumerable), typeof(DockingManager), + new FrameworkPropertyMetadata((IEnumerable)null, + new PropertyChangedCallback(OnAnchorablesSourceChanged))); + + /// + /// Gets or sets the AnchorablesSource property. This dependency property + /// indicates source collection of anchorables. + /// + public IEnumerable AnchorablesSource + { + get { return (IEnumerable)GetValue(AnchorablesSourceProperty); } + set { SetValue(AnchorablesSourceProperty, value); } + } + + /// + /// Handles changes to the AnchorablesSource property. + /// + private static void OnAnchorablesSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnAnchorablesSourceChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the AnchorablesSource property. + /// + protected virtual void OnAnchorablesSourceChanged(DependencyPropertyChangedEventArgs e) + { + DetachAnchorablesSource(Layout, e.OldValue as IEnumerable); + AttachAnchorablesSource(Layout, e.NewValue as IEnumerable); + } + + void AttachAnchorablesSource(LayoutRoot layout, IEnumerable anchorablesSource) + { + if (anchorablesSource == null) + return; + + if (layout == null) + return; + + //if (layout.Descendents().OfType().Any()) + // throw new InvalidOperationException("Unable to set the AnchorablesSource property if LayoutAnchorable objects are already present in the model"); + var anchorablesImported = layout.Descendents().OfType().Select(d => d.Content).ToArray(); + var anchorables = anchorablesSource as IEnumerable; + var listOfAnchorablesToImport = new List(anchorables.OfType()); + + foreach (var document in listOfAnchorablesToImport.ToArray()) + { + if (anchorablesImported.Contains(document)) + listOfAnchorablesToImport.Remove(document); + } + + LayoutAnchorablePane anchorablePane = null; + if (layout.ActiveContent != null) + { + //look for active content parent pane + anchorablePane = layout.ActiveContent.Parent as LayoutAnchorablePane; + } + + if (anchorablePane == null) + { + //look for a pane on the right side + anchorablePane = layout.Descendents().OfType().Where(pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right).FirstOrDefault(); + } + + if (anchorablePane == null) + { + //look for an available pane + anchorablePane = layout.Descendents().OfType().FirstOrDefault(); + } + + _suspendLayoutItemCreation = true; + foreach (var anchorableContentToImport in listOfAnchorablesToImport) + { + var anchorableToImport = new LayoutAnchorable() + { + Content = anchorableContentToImport + }; + + bool added = false; + if (LayoutUpdateStrategy != null) + { + added = LayoutUpdateStrategy.BeforeInsertAnchorable(layout, anchorableToImport, anchorablePane); + } + + if (!added) + { + if (anchorablePane == null) + { + var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; + if (layout.RootPanel != null) + { + mainLayoutPanel.Children.Add(layout.RootPanel); + } + + layout.RootPanel = mainLayoutPanel; + anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength(200.0, GridUnitType.Pixel) }; + mainLayoutPanel.Children.Add(anchorablePane); + } + + anchorablePane.Children.Add(anchorableToImport); + added = true; + } + + if (LayoutUpdateStrategy != null) + LayoutUpdateStrategy.AfterInsertAnchorable(layout, anchorableToImport); + + + CreateAnchorableLayoutItem(anchorableToImport); + + } + + _suspendLayoutItemCreation = false; + + var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; + if (anchorablesSourceAsNotifier != null) + anchorablesSourceAsNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(anchorablesSourceElementsChanged); + } + + internal bool SuspendAnchorablesSourceBinding = false; + + void anchorablesSourceElementsChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (Layout == null) + return; + + //When deserializing documents are created automatically by the deserializer + if (SuspendAnchorablesSourceBinding) + return; + + //handle remove + if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace) + { + if (e.OldItems != null) + { + var anchorablesToRemove = Layout.Descendents().OfType().Where(d => e.OldItems.Contains(d.Content)).ToArray(); + foreach (var anchorableToRemove in anchorablesToRemove) + { + (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( + anchorableToRemove); + } + } + } + + //handle add + if (e.NewItems != null && + (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add || + e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Replace)) + { + if (e.NewItems != null) + { + LayoutAnchorablePane anchorablePane = null; + + if (Layout.ActiveContent != null) + { + //look for active content parent pane + anchorablePane = Layout.ActiveContent.Parent as LayoutAnchorablePane; + } + + if (anchorablePane == null) + { + //look for a pane on the right side + anchorablePane = Layout.Descendents().OfType().Where(pane => !pane.IsHostedInFloatingWindow && pane.GetSide() == AnchorSide.Right).FirstOrDefault(); + } + + if (anchorablePane == null) + { + //look for an available pane + anchorablePane = Layout.Descendents().OfType().FirstOrDefault(); + } + + _suspendLayoutItemCreation = true; + foreach (var anchorableContentToImport in e.NewItems) + { + var anchorableToImport = new LayoutAnchorable() + { + Content = anchorableContentToImport + }; + + bool added = false; + if (LayoutUpdateStrategy != null) + { + added = LayoutUpdateStrategy.BeforeInsertAnchorable(Layout, anchorableToImport, anchorablePane); + } + + if (!added) + { + if (anchorablePane == null) + { + var mainLayoutPanel = new LayoutPanel() { Orientation = Orientation.Horizontal }; + if (Layout.RootPanel != null) + { + mainLayoutPanel.Children.Add(Layout.RootPanel); + } + + Layout.RootPanel = mainLayoutPanel; + anchorablePane = new LayoutAnchorablePane() { DockWidth = new GridLength(200.0, GridUnitType.Pixel) }; + mainLayoutPanel.Children.Add(anchorablePane); + } + + anchorablePane.Children.Add(anchorableToImport); + added = true; + } + + if (LayoutUpdateStrategy != null) + { + LayoutUpdateStrategy.AfterInsertAnchorable(Layout, anchorableToImport); + } + + var root = anchorableToImport.Root; + + if (root != null && root.Manager == this) + { + CreateAnchorableLayoutItem(anchorableToImport); + } + + } + _suspendLayoutItemCreation = false; + } + } + + if (e.Action == NotifyCollectionChangedAction.Reset) + { + //NOTE: I'm going to clear every anchorable present in layout but + //some anchorable may have been added directly to the layout, for now I clear them too + var anchorablesToRemove = Layout.Descendents().OfType().ToArray(); + foreach (var anchorableToRemove in anchorablesToRemove) + { + (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( + anchorableToRemove); + } + } + + if (Layout != null) + Layout.CollectGarbage(); + } + + void DetachAnchorablesSource(LayoutRoot layout, IEnumerable anchorablesSource) + { + if (anchorablesSource == null) + return; + + if (layout == null) + return; + + var anchorablesToRemove = layout.Descendents().OfType() + .Where(d => anchorablesSource.Contains(d.Content)).ToArray(); + + foreach (var anchorableToRemove in anchorablesToRemove) + { + (anchorableToRemove.Parent as ILayoutContainer).RemoveChild( + anchorableToRemove); + } + + var anchorablesSourceAsNotifier = anchorablesSource as INotifyCollectionChanged; + if (anchorablesSourceAsNotifier != null) + anchorablesSourceAsNotifier.CollectionChanged -= new NotifyCollectionChangedEventHandler(anchorablesSourceElementsChanged); + } + + #endregion + + internal void _ExecuteCloseCommand(LayoutAnchorable anchorable) + { + var model = anchorable as LayoutAnchorable; + if (model != null && model.TestCanClose()) + { + if (model.IsAutoHidden) + model.ToggleAutoHide(); + + model.Close(); + return; + } + } + + internal void _ExecuteHideCommand(LayoutAnchorable anchorable) + { + var model = anchorable as LayoutAnchorable; + if (model != null) + { + //by default hide the anchorable + model.Hide(); + } + } + + internal void _ExecuteAutoHideCommand(LayoutAnchorable _anchorable) + { + _anchorable.ToggleAutoHide(); + } + + internal void _ExecuteFloatCommand(LayoutContent contentToFloat) + { + contentToFloat.Float(); + } + + internal void _ExecuteDockCommand(LayoutAnchorable anchorable) + { + anchorable.Dock(); + } + + internal void _ExecuteDockAsDocumentCommand(LayoutContent content) + { + content.DockAsDocument(); + } + + #region ActiveContent + + /// + /// ActiveContent Dependency Property + /// + public static readonly DependencyProperty ActiveContentProperty = + DependencyProperty.Register("ActiveContent", typeof(object), typeof(DockingManager), + new FrameworkPropertyMetadata((object)null, + new PropertyChangedCallback(OnActiveContentChanged))); + + /// + /// Gets or sets the ActiveContent property. This dependency property + /// indicates the content currently active. + /// + public object ActiveContent + { + get { return (object)GetValue(ActiveContentProperty); } + set { SetValue(ActiveContentProperty, value); } + } + + /// + /// Handles changes to the ActiveContent property. + /// + private static void OnActiveContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).InternalSetActiveContent(e.NewValue); + ((DockingManager)d).OnActiveContentChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the ActiveContent property. + /// + protected virtual void OnActiveContentChanged(DependencyPropertyChangedEventArgs e) + { + if (ActiveContentChanged != null) + ActiveContentChanged(this, EventArgs.Empty); + } + + + bool _insideInternalSetActiveContent = false; + void InternalSetActiveContent(object contentObject) + { + var layoutContent = Layout.Descendents().OfType().FirstOrDefault(lc => lc == contentObject || lc.Content == contentObject); + _insideInternalSetActiveContent = true; + Layout.ActiveContent = layoutContent; + _insideInternalSetActiveContent = false; + } + + public event EventHandler ActiveContentChanged; + + #endregion + + #region AnchorableContextMenu + + /// + /// AnchorableContextMenu Dependency Property + /// + public static readonly DependencyProperty AnchorableContextMenuProperty = + DependencyProperty.Register("AnchorableContextMenu", typeof(ContextMenu), typeof(DockingManager), + new FrameworkPropertyMetadata((ContextMenu)null)); + + /// + /// Gets or sets the AnchorableContextMenu property. This dependency property + /// indicates the context menu to show up for anchorables. + /// + public ContextMenu AnchorableContextMenu + { + get { return (ContextMenu)GetValue(AnchorableContextMenuProperty); } + set { SetValue(AnchorableContextMenuProperty, value); } + } + + #endregion + + #region Theme + + /// + /// Theme Dependency Property + /// + public static readonly DependencyProperty ThemeProperty = + DependencyProperty.Register("Theme", typeof(Theme), typeof(DockingManager), + new FrameworkPropertyMetadata(null, + new PropertyChangedCallback(OnThemeChanged))); + + /// + /// Gets or sets the Theme property. This dependency property + /// indicates the theme to use for AvalonDock controls. + /// + public Theme Theme + { + get { return (Theme)GetValue(ThemeProperty); } + set { SetValue(ThemeProperty, value); } + } + + /// + /// Handles changes to the Theme property. + /// + private static void OnThemeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnThemeChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the Theme property. + /// + protected virtual void OnThemeChanged(DependencyPropertyChangedEventArgs e) + { + var oldTheme = e.OldValue as Theme; + var newTheme = e.NewValue as Theme; + var resources = Application.Current == null ? this.Resources : Application.Current.Resources; + if (oldTheme != null) + { + var resourceDictionaryToRemove = + resources.MergedDictionaries.FirstOrDefault(r => r.Source == oldTheme.GetResourceUri()); + if (resourceDictionaryToRemove != null) + resources.MergedDictionaries.Remove( + resourceDictionaryToRemove); + } + + if (newTheme != null) + { + resources.MergedDictionaries.Add(new ResourceDictionary() { Source = newTheme.GetResourceUri() }); + } + + if (Application.Current == null) + { + foreach (var fwc in _fwList) + fwc.UpdateThemeResources(oldTheme); + + if (_navigatorWindow != null) + _navigatorWindow.UpdateThemeResources(); + + if (_overlayWindow != null) + _overlayWindow.UpdateThemeResources(); + } + } + + #endregion + + #region GridSplitterWidth + + /// + /// GridSplitterWidth Dependency Property + /// + public static readonly DependencyProperty GridSplitterWidthProperty = + DependencyProperty.Register("GridSplitterWidth", typeof(double), typeof(DockingManager), + new FrameworkPropertyMetadata((double)6.0)); + + /// + /// Gets or sets the GridSplitterWidth property. This dependency property + /// indicates width of grid splitters. + /// + public double GridSplitterWidth + { + get { return (double)GetValue(GridSplitterWidthProperty); } + set { SetValue(GridSplitterWidthProperty, value); } + } + + #endregion + + #region GridSplitterHeight + + /// + /// GridSplitterHeight Dependency Property + /// + public static readonly DependencyProperty GridSplitterHeightProperty = + DependencyProperty.Register("GridSplitterHeight", typeof(double), typeof(DockingManager), + new FrameworkPropertyMetadata((double)6.0)); + + /// + /// Gets or sets the GridSplitterHeight property. This dependency property + /// indicates height of grid splitters. + /// + public double GridSplitterHeight + { + get { return (double)GetValue(GridSplitterHeightProperty); } + set { SetValue(GridSplitterHeightProperty, value); } + } + + #endregion + + internal void _ExecuteContentActivateCommand(LayoutContent content) + { + content.IsActive = true; + } + + #region DocumentPaneMenuItemHeaderTemplate + + /// + /// DocumentPaneMenuItemHeaderTemplate Dependency Property + /// + public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateProperty = + DependencyProperty.Register("DocumentPaneMenuItemHeaderTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null, + new PropertyChangedCallback(OnDocumentPaneMenuItemHeaderTemplateChanged), + new CoerceValueCallback(CoerceDocumentPaneMenuItemHeaderTemplateValue))); + + /// + /// Gets or sets the DocumentPaneMenuItemHeaderTemplate property. This dependency property + /// indicates the header template to use while creating menu items for the document panes. + /// + public DataTemplate DocumentPaneMenuItemHeaderTemplate + { + get { return (DataTemplate)GetValue(DocumentPaneMenuItemHeaderTemplateProperty); } + set { SetValue(DocumentPaneMenuItemHeaderTemplateProperty, value); } + } + + /// + /// Handles changes to the DocumentPaneMenuItemHeaderTemplate property. + /// + private static void OnDocumentPaneMenuItemHeaderTemplateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentPaneMenuItemHeaderTemplateChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplate property. + /// + protected virtual void OnDocumentPaneMenuItemHeaderTemplateChanged(DependencyPropertyChangedEventArgs e) + { + } + + /// + /// Coerces the DocumentPaneMenuItemHeaderTemplate value. + /// + private static object CoerceDocumentPaneMenuItemHeaderTemplateValue(DependencyObject d, object value) + { + if (value != null && + d.GetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty) != null) + return null; + if (value == null) + return d.GetValue(DocumentHeaderTemplateProperty); + + return value; + } + + #endregion + + #region DocumentPaneMenuItemHeaderTemplateSelector + + /// + /// DocumentPaneMenuItemHeaderTemplateSelector Dependency Property + /// + public static readonly DependencyProperty DocumentPaneMenuItemHeaderTemplateSelectorProperty = + DependencyProperty.Register("DocumentPaneMenuItemHeaderTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null, + new PropertyChangedCallback(OnDocumentPaneMenuItemHeaderTemplateSelectorChanged), + new CoerceValueCallback(CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue))); + + /// + /// Gets or sets the DocumentPaneMenuItemHeaderTemplateSelector property. This dependency property + /// indicates the data template selector to use for the menu items show when user select the DocumentPane document switch context menu. + /// + public DataTemplateSelector DocumentPaneMenuItemHeaderTemplateSelector + { + get { return (DataTemplateSelector)GetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty); } + set { SetValue(DocumentPaneMenuItemHeaderTemplateSelectorProperty, value); } + } + + /// + /// Handles changes to the DocumentPaneMenuItemHeaderTemplateSelector property. + /// + private static void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the DocumentPaneMenuItemHeaderTemplateSelector property. + /// + protected virtual void OnDocumentPaneMenuItemHeaderTemplateSelectorChanged(DependencyPropertyChangedEventArgs e) + { + if (e.NewValue != null && + DocumentPaneMenuItemHeaderTemplate != null) + DocumentPaneMenuItemHeaderTemplate = null; + + } + + /// + /// Coerces the DocumentPaneMenuItemHeaderTemplateSelector value. + /// + private static object CoerceDocumentPaneMenuItemHeaderTemplateSelectorValue(DependencyObject d, object value) + { + return value; + } + + #endregion + + #region IconContentTemplate + + /// + /// IconContentTemplate Dependency Property + /// + public static readonly DependencyProperty IconContentTemplateProperty = + DependencyProperty.Register("IconContentTemplate", typeof(DataTemplate), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplate)null)); + + /// + /// Gets or sets the IconContentTemplate property. This dependency property + /// indicates the data template to use while extracting the icon from model. + /// + public DataTemplate IconContentTemplate + { + get { return (DataTemplate)GetValue(IconContentTemplateProperty); } + set { SetValue(IconContentTemplateProperty, value); } + } + + #endregion + + #region IconContentTemplateSelector + + /// + /// IconContentTemplateSelector Dependency Property + /// + public static readonly DependencyProperty IconContentTemplateSelectorProperty = + DependencyProperty.Register("IconContentTemplateSelector", typeof(DataTemplateSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((DataTemplateSelector)null)); + + /// + /// Gets or sets the IconContentTemplateSelector property. This dependency property + /// indicates data template selector to use while selecting the datatamplate for content icons. + /// + public DataTemplateSelector IconContentTemplateSelector + { + get { return (DataTemplateSelector)GetValue(IconContentTemplateSelectorProperty); } + set { SetValue(IconContentTemplateSelectorProperty, value); } + } + + #endregion + + #region LayoutItems + + List _layoutItems = new List(); + + public List LayoutItems => _layoutItems; + + bool _suspendLayoutItemCreation = false; + + void DetachLayoutItems() + { + if (Layout != null) + { + _layoutItems.ForEach(i => i.Detach()); + _layoutItems.Clear(); + Layout.ElementAdded -= new EventHandler(Layout_ElementAdded); + Layout.ElementRemoved -= new EventHandler(Layout_ElementRemoved); + } + } + + void Layout_ElementRemoved(object sender, LayoutElementEventArgs e) + { + if (_suspendLayoutItemCreation) + return; + + CollectLayoutItemsDeleted(); + } + + void Layout_ElementAdded(object sender, LayoutElementEventArgs e) + { + if (_suspendLayoutItemCreation) + return; + + foreach (var content in Layout.Descendents().OfType()) + { + if (content is LayoutDocument) + CreateDocumentLayoutItem(content as LayoutDocument); + else //if (content is LayoutAnchorable) + CreateAnchorableLayoutItem(content as LayoutAnchorable); + } + + CollectLayoutItemsDeleted(); + } + + + DispatcherOperation _collectLayoutItemsOperations = null; + void CollectLayoutItemsDeleted() + { + if (_collectLayoutItemsOperations != null) + return; + _collectLayoutItemsOperations = Dispatcher.BeginInvoke(new Action(() => + { + _collectLayoutItemsOperations = null; + foreach (var itemToRemove in _layoutItems.Where(item => item.LayoutElement.Root != Layout).ToArray()) + { + + if (itemToRemove != null && + itemToRemove.Model != null && + itemToRemove.Model is UIElement) + { + //((ILogicalChildrenContainer)this).InternalRemoveLogicalChild(itemToRemove.Model as UIElement); + } + + itemToRemove.Detach(); + _layoutItems.Remove(itemToRemove); + + } + })); + } + + + void AttachLayoutItems() + { + if (Layout != null) + { + foreach (var document in Layout.Descendents().OfType().ToArray()) + { + CreateDocumentLayoutItem(document); + //var documentItem = new LayoutDocumentItem(); + //documentItem.Attach(document); + //ApplyStyleToLayoutItem(documentItem); + //_layoutItems.Add(documentItem); + } + foreach (var anchorable in Layout.Descendents().OfType().ToArray()) + { + CreateAnchorableLayoutItem(anchorable); + //var anchorableItem = new LayoutAnchorableItem(); + //anchorableItem.Attach(anchorable); + //ApplyStyleToLayoutItem(anchorableItem); + //_layoutItems.Add(anchorableItem); + } + + Layout.ElementAdded += new EventHandler(Layout_ElementAdded); + Layout.ElementRemoved += new EventHandler(Layout_ElementRemoved); + } + } + + void ApplyStyleToLayoutItem(LayoutItem layoutItem) + { + layoutItem._ClearDefaultBindings(); + if (LayoutItemContainerStyle != null) + layoutItem.Style = LayoutItemContainerStyle; + else if (LayoutItemContainerStyleSelector != null) + layoutItem.Style = LayoutItemContainerStyleSelector.SelectStyle(layoutItem.Model, layoutItem); + layoutItem._SetDefaultBindings(); + } + + void CreateAnchorableLayoutItem(LayoutAnchorable contentToAttach) + { + if (_layoutItems.Any(item => item.LayoutElement == contentToAttach)) + return; + + var layoutItem = new LayoutAnchorableItem(); + layoutItem.Attach(contentToAttach); + ApplyStyleToLayoutItem(layoutItem); + _layoutItems.Add(layoutItem); + + if (contentToAttach != null && + contentToAttach.Content != null && + contentToAttach.Content is UIElement) + { + InternalAddLogicalChild(contentToAttach.Content); + } + + } + + void CreateDocumentLayoutItem(LayoutDocument contentToAttach) + { + if (_layoutItems.Any(item => item.LayoutElement == contentToAttach)) + return; + + var layoutItem = new LayoutDocumentItem(); + layoutItem.Attach(contentToAttach); + ApplyStyleToLayoutItem(layoutItem); + _layoutItems.Add(layoutItem); + + if (contentToAttach != null && + contentToAttach.Content != null && + contentToAttach.Content is UIElement) + { + InternalAddLogicalChild(contentToAttach.Content); + } + + } + + #region LayoutItemContainerStyle + + /// + /// LayoutItemContainerStyle Dependency Property + /// + public static readonly DependencyProperty LayoutItemContainerStyleProperty = + DependencyProperty.Register("LayoutItemContainerStyle", typeof(Style), typeof(DockingManager), + new FrameworkPropertyMetadata((Style)null, + new PropertyChangedCallback(OnLayoutItemContainerStyleChanged))); + + /// + /// Gets or sets the LayoutItemContainerStyle property. This dependency property + /// indicates the style to apply to LayoutDocumentItem objects. A LayoutDocumentItem object is created when a new LayoutDocument is created inside the current Layout. + /// + public Style LayoutItemContainerStyle + { + get { return (Style)GetValue(LayoutItemContainerStyleProperty); } + set { SetValue(LayoutItemContainerStyleProperty, value); } + } + + /// + /// Handles changes to the LayoutItemContainerStyle property. + /// + private static void OnLayoutItemContainerStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutItemContainerStyleChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyle property. + /// + protected virtual void OnLayoutItemContainerStyleChanged(DependencyPropertyChangedEventArgs e) + { + AttachLayoutItems(); + } + + #endregion + + #region LayoutItemContainerStyleSelector + + /// + /// LayoutItemContainerStyleSelector Dependency Property + /// + public static readonly DependencyProperty LayoutItemContainerStyleSelectorProperty = + DependencyProperty.Register("LayoutItemContainerStyleSelector", typeof(StyleSelector), typeof(DockingManager), + new FrameworkPropertyMetadata((StyleSelector)null, + new PropertyChangedCallback(OnLayoutItemContainerStyleSelectorChanged))); + + /// + /// Gets or sets the LayoutItemContainerStyleSelector property. This dependency property + /// indicates style selector of the LayoutDocumentItemStyle. + /// + public StyleSelector LayoutItemContainerStyleSelector + { + get { return (StyleSelector)GetValue(LayoutItemContainerStyleSelectorProperty); } + set { SetValue(LayoutItemContainerStyleSelectorProperty, value); } + } + + /// + /// Handles changes to the LayoutItemContainerStyleSelector property. + /// + private static void OnLayoutItemContainerStyleSelectorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + ((DockingManager)d).OnLayoutItemContainerStyleSelectorChanged(e); + } + + /// + /// Provides derived classes an opportunity to handle changes to the LayoutItemContainerStyleSelector property. + /// + protected virtual void OnLayoutItemContainerStyleSelectorChanged(DependencyPropertyChangedEventArgs e) + { + AttachLayoutItems(); + } + + #endregion + + /// + /// Return the LayoutItem wrapper for the content passed as argument + /// + /// LayoutContent to search + /// Either a LayoutAnchorableItem or LayoutDocumentItem which contains the LayoutContent passed as argument + public LayoutItem GetLayoutItemFromModel(LayoutContent content) + { + return _layoutItems.FirstOrDefault(item => item.LayoutElement == content); + } + #endregion + + #region NavigatorWindow + NavigatorWindow _navigatorWindow = null; + + void ShowNavigatorWindow() + { + if (_navigatorWindow == null) + { + _navigatorWindow = new NavigatorWindow(this) + { + Owner = Window.GetWindow(this), + WindowStartupLocation = WindowStartupLocation.CenterOwner + }; + } + + _navigatorWindow.ShowDialog(); + _navigatorWindow = null; + + Trace.WriteLine( "ShowNavigatorWindow()" ); + } + + bool IsNavigatorWindowActive + { + get { return _navigatorWindow != null; } + } + + + protected override void OnPreviewKeyDown(KeyEventArgs e) + { + Trace.WriteLine( string.Format( "OnPreviewKeyDown({0})", e.Key ) ); + if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) + { + if (e.IsDown && e.Key == Key.Tab) + { + if (!IsNavigatorWindowActive) + { + ShowNavigatorWindow(); + e.Handled = true; + } + } + } + + base.OnPreviewKeyDown(e); + } + + #endregion + + #region ShowSystemMenu + + /// + /// ShowSystemMenu Dependency Property + /// + public static readonly DependencyProperty ShowSystemMenuProperty = + DependencyProperty.Register("ShowSystemMenu", typeof(bool), typeof(DockingManager), + new FrameworkPropertyMetadata((bool)true)); + + /// + /// Gets or sets the ShowSystemMenu property. This dependency property + /// indicates if floating windows should show the system menu when a custom context menu is not defined. + /// + public bool ShowSystemMenu + { + get { return (bool)GetValue(ShowSystemMenuProperty); } + set { SetValue(ShowSystemMenuProperty, value); } + } + + #endregion + + #region AllowMixedOrientation + + /// + /// AllowMixedOrientation Dependency Property + /// + public static readonly DependencyProperty AllowMixedOrientationProperty = + DependencyProperty.Register("AllowMixedOrientation", typeof(bool), typeof(DockingManager), + new FrameworkPropertyMetadata((bool)false)); + + /// + /// Gets or sets the AllowMixedOrientation property. This dependency property + /// indicates if the manager should allow mixed orientation for document panes. + /// + public bool AllowMixedOrientation + { + get { return (bool)GetValue(AllowMixedOrientationProperty); } + set { SetValue(AllowMixedOrientationProperty, value); } + } + + #endregion + + + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs index aae6fc1b..958fae75 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutContent.cs @@ -27,742 +27,784 @@ using System.ComponentModel; namespace Xceed.Wpf.AvalonDock.Layout { - [ContentProperty("Content")] - [Serializable] - public abstract class LayoutContent : LayoutElement, IXmlSerializable, ILayoutElementForFloatingWindow, IComparable, ILayoutPreviousContainer - { - internal LayoutContent() - { } - - #region Title - - private string _title = null; - public string Title - { - get { return _title; } - set - { - if (_title != value) - { - RaisePropertyChanging("Title"); - _title = value; - RaisePropertyChanged("Title"); - } - } - } - - #endregion - - #region Content - [NonSerialized] - private object _content = null; - [XmlIgnore] - public object Content - { - get { return _content; } - set - { - if (_content != value) - { - RaisePropertyChanging("Content"); - _content = value; - RaisePropertyChanged("Content"); - } - } - } - - #endregion - - #region ContentId - - private string _contentId = null; - public string ContentId - { - get - { - if (_contentId == null) - { - var contentAsControl = _content as FrameworkElement; - if (contentAsControl != null && !string.IsNullOrWhiteSpace(contentAsControl.Name)) - return contentAsControl.Name; - } - return _contentId; - } - set - { - if (_contentId != value) - { - _contentId = value; - RaisePropertyChanged("ContentId"); - } - } - } - - #endregion - - #region IsSelected - - private bool _isSelected = false; - public bool IsSelected - { - get { return _isSelected; } - set - { - if (_isSelected != value) - { - bool oldValue = _isSelected; - RaisePropertyChanging("IsSelected"); - _isSelected = value; - var parentSelector = (Parent as ILayoutContentSelector); - if (parentSelector != null) - parentSelector.SelectedContentIndex = _isSelected ? parentSelector.IndexOf(this) : -1; - OnIsSelectedChanged(oldValue, value); - RaisePropertyChanged("IsSelected"); - } - } - } - - /// - /// Provides derived classes an opportunity to handle changes to the IsSelected property. - /// - protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) - { - if (IsSelectedChanged != null) - IsSelectedChanged(this, EventArgs.Empty); - } - - public event EventHandler IsSelectedChanged; - - #endregion - - #region IsActive - - [field: NonSerialized] - private bool _isActive = false; - [XmlIgnore] - public bool IsActive - { - get { return _isActive; } - set - { - if (_isActive != value) - { - RaisePropertyChanging("IsActive"); - bool oldValue = _isActive; - - _isActive = value; - - var root = Root; - if (root != null && _isActive) - root.ActiveContent = this; - - if (_isActive) - IsSelected = true; - - OnIsActiveChanged(oldValue, value); - RaisePropertyChanged("IsActive"); - } - } - } - - /// - /// Provides derived classes an opportunity to handle changes to the IsActive property. - /// - protected virtual void OnIsActiveChanged(bool oldValue, bool newValue) - { - if (newValue) - LastActivationTimeStamp = DateTime.Now; - - if (IsActiveChanged != null) - IsActiveChanged(this, EventArgs.Empty); - } - - public event EventHandler IsActiveChanged; - - #endregion - - #region IsLastFocusedDocument - - private bool _isLastFocusedDocument = false; - public bool IsLastFocusedDocument - { - get { return _isLastFocusedDocument; } - internal set - { - if (_isLastFocusedDocument != value) - { - RaisePropertyChanging("IsLastFocusedDocument"); - _isLastFocusedDocument = value; - RaisePropertyChanged("IsLastFocusedDocument"); - } - } - } - - #endregion - - #region PreviousContainer - - [field: NonSerialized] - private ILayoutContainer _previousContainer = null; - - [XmlIgnore] - ILayoutContainer ILayoutPreviousContainer.PreviousContainer - { - get { return _previousContainer; } - set - { - if (_previousContainer != value) - { - _previousContainer = value; - RaisePropertyChanged("PreviousContainer"); - - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null && - paneSerializable.Id == null) - paneSerializable.Id = Guid.NewGuid().ToString(); - } - } - } - - protected ILayoutContainer PreviousContainer - { - get { return ((ILayoutPreviousContainer)this).PreviousContainer; } - set { ((ILayoutPreviousContainer)this).PreviousContainer = value; } - } - - [XmlIgnore] - string ILayoutPreviousContainer.PreviousContainerId - { - get; - set; - } - - protected string PreviousContainerId - { - get { return ((ILayoutPreviousContainer)this).PreviousContainerId; } - set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; } - } - - #endregion - - #region PreviousContainerIndex - [field: NonSerialized] - private int _previousContainerIndex = -1; - [XmlIgnore] - public int PreviousContainerIndex - { - get { return _previousContainerIndex; } - set - { - if (_previousContainerIndex != value) - { - _previousContainerIndex = value; - RaisePropertyChanged("PreviousContainerIndex"); - } - } - } - - #endregion - - #region LastActivationTimeStamp - - private DateTime? _lastActivationTimeStamp = null; - public DateTime? LastActivationTimeStamp - { - get { return _lastActivationTimeStamp; } - set - { - if (_lastActivationTimeStamp != value) - { - _lastActivationTimeStamp = value; - RaisePropertyChanged("LastActivationTimeStamp"); - } - } - } - - #endregion - - protected override void OnParentChanging(ILayoutContainer oldValue, ILayoutContainer newValue) - { - var root = Root; - - if (oldValue != null) - IsSelected = false; - - //if (root != null && _isActive && newValue == null) - // root.ActiveContent = null; - - base.OnParentChanging(oldValue, newValue); - } - - protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) - { - if (IsSelected && Parent != null && Parent is ILayoutContentSelector) - { - var parentSelector = (Parent as ILayoutContentSelector); - parentSelector.SelectedContentIndex = parentSelector.IndexOf(this); - } - - //var root = Root; - //if (root != null && _isActive) - // root.ActiveContent = this; - - base.OnParentChanged(oldValue, newValue); - } - - /// - /// Test if the content can be closed - /// - /// - internal bool TestCanClose() - { - CancelEventArgs args = new CancelEventArgs(); - - OnClosing(args); - - if (args.Cancel) - return false; - - return true; - } - - /// - /// Close the content - /// - /// Please note that usually the anchorable is only hidden (not closed). By default when user click the X button it only hides the content. - public void Close() - { - var root = Root; - var parentAsContainer = Parent as ILayoutContainer; - parentAsContainer.RemoveChild(this); - if (root != null) - root.CollectGarbage(); - - OnClosed(); - } - - /// - /// Event fired when the content is closed (i.e. removed definitely from the layout) - /// - public event EventHandler Closed; - - protected virtual void OnClosed() - { - if (Closed != null) - Closed(this, EventArgs.Empty); - } - - /// - /// Event fired when the content is about to be closed (i.e. removed definitely from the layout) - /// - /// Please note that LayoutAnchorable also can be hidden. Usually user hide anchorables when click the 'X' button. To completely close - /// an anchorable the user should click the 'Close' menu item from the context menu. When an LayoutAnchorable is hidden its visibility changes to false and - /// IsHidden property is set to true. - /// Hanlde the Hiding event for the LayoutAnchorable to cancel the hide operation. - public event EventHandler Closing; - - protected virtual void OnClosing(CancelEventArgs args) - { - if (Closing != null) - Closing(this, args); - } - - public System.Xml.Schema.XmlSchema GetSchema() - { - return null; - } - - public virtual void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("Title")) - Title = reader.Value; - //if (reader.MoveToAttribute("IconSource")) - // IconSource = new Uri(reader.Value, UriKind.RelativeOrAbsolute); - - if (reader.MoveToAttribute("IsSelected")) - IsSelected = bool.Parse(reader.Value); - if (reader.MoveToAttribute("ContentId")) - ContentId = reader.Value; - if (reader.MoveToAttribute("IsLastFocusedDocument")) - IsLastFocusedDocument = bool.Parse(reader.Value); - if (reader.MoveToAttribute("PreviousContainerId")) - PreviousContainerId = reader.Value; - if (reader.MoveToAttribute("PreviousContainerIndex")) - PreviousContainerIndex = int.Parse(reader.Value); - - if (reader.MoveToAttribute("FloatingLeft")) - FloatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingTop")) - FloatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingWidth")) - FloatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingHeight")) - FloatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("IsMaximized")) - IsMaximized = bool.Parse(reader.Value); - if (reader.MoveToAttribute("CanClose")) - CanClose = bool.Parse(reader.Value); - if (reader.MoveToAttribute("CanFloat")) - CanFloat = bool.Parse(reader.Value); - if (reader.MoveToAttribute("LastActivationTimeStamp")) - LastActivationTimeStamp = DateTime.Parse(reader.Value, CultureInfo.InvariantCulture); - - reader.Read(); - } - - public virtual void WriteXml(System.Xml.XmlWriter writer) - { - if (!string.IsNullOrWhiteSpace(Title)) - writer.WriteAttributeString("Title", Title); - - //if (IconSource != null) - // writer.WriteAttributeString("IconSource", IconSource.ToString()); - - if (IsSelected) - writer.WriteAttributeString("IsSelected", IsSelected.ToString()); - - if (IsLastFocusedDocument) - writer.WriteAttributeString("IsLastFocusedDocument", IsLastFocusedDocument.ToString()); - - if (!string.IsNullOrWhiteSpace(ContentId)) - writer.WriteAttributeString("ContentId", ContentId); - - - if (ToolTip != null && ToolTip is string) - if (!string.IsNullOrWhiteSpace((string)ToolTip)) - writer.WriteAttributeString("ToolTip", (string)ToolTip); - - if (FloatingLeft != 0.0) - writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); - if (FloatingTop != 0.0) - writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); - if (FloatingWidth != 0.0) - writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); - if (FloatingHeight != 0.0) - writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); - - if (IsMaximized) - writer.WriteAttributeString("IsMaximized", IsMaximized.ToString()); - if (!CanClose) - writer.WriteAttributeString("CanClose", CanClose.ToString()); - if (!CanFloat) - writer.WriteAttributeString("CanFloat", CanFloat.ToString()); - - if (LastActivationTimeStamp != null) - writer.WriteAttributeString("LastActivationTimeStamp", LastActivationTimeStamp.Value.ToString(CultureInfo.InvariantCulture)); - - if (_previousContainer != null) - { - var paneSerializable = _previousContainer as ILayoutPaneSerializable; - if (paneSerializable != null) - { - writer.WriteAttributeString("PreviousContainerId", paneSerializable.Id); - writer.WriteAttributeString("PreviousContainerIndex", _previousContainerIndex.ToString()); - } - } - - } - - #region FloatingWidth - - private double _floatingWidth = 0.0; - public double FloatingWidth - { - get { return _floatingWidth; } - set - { - if (_floatingWidth != value) - { - RaisePropertyChanging("FloatingWidth"); - _floatingWidth = value; - RaisePropertyChanged("FloatingWidth"); - } - } - } - - #endregion - - #region FloatingHeight - - private double _floatingHeight = 0.0; - public double FloatingHeight - { - get { return _floatingHeight; } - set - { - if (_floatingHeight != value) - { - RaisePropertyChanging("FloatingHeight"); - _floatingHeight = value; - RaisePropertyChanged("FloatingHeight"); - } - } - } - - #endregion - - #region FloatingLeft - - private double _floatingLeft = 0.0; - public double FloatingLeft - { - get { return _floatingLeft; } - set - { - if (_floatingLeft != value) - { - RaisePropertyChanging("FloatingLeft"); - _floatingLeft = value; - RaisePropertyChanged("FloatingLeft"); - } - } - } - - #endregion - - #region FloatingTop - - private double _floatingTop = 0.0; - public double FloatingTop - { - get { return _floatingTop; } - set - { - if (_floatingTop != value) - { - RaisePropertyChanging("FloatingTop"); - _floatingTop = value; - RaisePropertyChanged("FloatingTop"); - } - } - } - - #endregion - - #region IsMaximized - - private bool _isMaximized = false; - public bool IsMaximized - { - get { return _isMaximized; } - set - { - if (_isMaximized != value) - { - RaisePropertyChanging("IsMaximized"); - _isMaximized = value; - RaisePropertyChanged("IsMaximized"); - } - } - } - - #endregion - - #region ToolTip - - private object _toolTip = null; - public object ToolTip - { - get { return _toolTip; } - set - { - if (_toolTip != value) - { - _toolTip = value; - RaisePropertyChanged("ToolTip"); - } - } - } - - #endregion - - public bool IsFloating - { - get { return this.FindParent() != null; } - } - - #region IconSource - - private ImageSource _iconSource = null; - public ImageSource IconSource - { - get { return _iconSource; } - set - { - if (_iconSource != value) - { - _iconSource = value; - RaisePropertyChanged("IconSource"); - } - } - } - - #endregion - - public int CompareTo(LayoutContent other) - { - var contentAsComparable = Content as IComparable; - if (contentAsComparable != null) - { - return contentAsComparable.CompareTo(other.Content); - } - - return string.Compare(Title, other.Title); - } - - /// - /// Float the content in a popup window - /// - public void Float() - { - if (PreviousContainer != null && - PreviousContainer.FindParent() != null) - { - - var currentContainer = Parent as ILayoutPane; - var currentContainerIndex = (currentContainer as ILayoutGroup).IndexOfChild(this); - var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; - - if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) - previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); - else - previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); - - PreviousContainer = currentContainer; - PreviousContainerIndex = currentContainerIndex; - - IsSelected = true; - IsActive = true; - - Root.CollectGarbage(); - } - else - { - Root.Manager.StartDraggingFloatingWindowForContent(this, false); - - IsSelected = true; - IsActive = true; - } - - } - - /// - /// Dock the content as document - /// - public void DockAsDocument() - { - var root = Root as LayoutRoot; - if (root == null) - throw new InvalidOperationException(); - if (Parent is LayoutDocumentPane) - return; - - if (PreviousContainer is LayoutDocumentPane) - { - Dock(); - return; - } - - LayoutDocumentPane newParentPane; - if (root.LastFocusedDocument != null) - { - newParentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; - } - else - { - newParentPane = root.Descendents().OfType().FirstOrDefault(); - } - - if (newParentPane != null) - { - newParentPane.Children.Add(this); - root.CollectGarbage(); - } - - IsSelected = true; - IsActive = true; - } - - /// - /// Re-dock the content to its previous container - /// - public void Dock() - { - if (PreviousContainer != null) - { - var currentContainer = Parent as ILayoutContainer; - var currentContainerIndex = (currentContainer is ILayoutGroup) ? (currentContainer as ILayoutGroup).IndexOfChild(this) : -1; - var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; - - if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) - previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); - else - previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); - - if (currentContainerIndex > -1) - { - PreviousContainer = currentContainer; - PreviousContainerIndex = currentContainerIndex; - } - else - { - PreviousContainer = null; - PreviousContainerIndex = 0; - } - - IsSelected = true; - IsActive = true; - } - else - { - InternalDock(); - } - - - Root.CollectGarbage(); - - } - - protected virtual void InternalDock() - { - - } - - - #region CanClose - - private bool _canClose = true; - public bool CanClose - { - get { return _canClose; } - set - { - if (_canClose != value) - { - _canClose = value; - RaisePropertyChanged("CanClose"); - } - } - } - - #endregion - - #region CanFloat - - private bool _canFloat = true; - public bool CanFloat - { - get { return _canFloat; } - set - { - if (_canFloat != value) - { - _canFloat = value; - RaisePropertyChanged("CanFloat"); - } - } - } - - #endregion - } + [ContentProperty("Content")] + [Serializable] + public abstract class LayoutContent : LayoutElement, IXmlSerializable, ILayoutElementForFloatingWindow, IComparable, ILayoutPreviousContainer + { + internal LayoutContent() + { } + + #region Title + + public static readonly DependencyProperty TitleProperty = + DependencyProperty.Register("Title", typeof(string), typeof(LayoutContent), new UIPropertyMetadata(null, OnTitlePropertyChanged, CoerceTitleValue)); + + public string Title + { + get { return (string)GetValue(TitleProperty); } + set { SetValue(TitleProperty, value); } + } + + private static object CoerceTitleValue(DependencyObject obj, object value) + { + var lc = (LayoutContent)obj; + if (((string)value) != lc.Title) + { + lc.RaisePropertyChanging(LayoutContent.TitleProperty.Name); + } + return value; + } + + private static void OnTitlePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + ((LayoutContent)obj).RaisePropertyChanged(LayoutContent.TitleProperty.Name); + } + + #endregion + + #region Content + [NonSerialized] + private object _content = null; + [XmlIgnore] + public object Content + { + get { return _content; } + set + { + if (_content != value) + { + RaisePropertyChanging("Content"); + _content = value; + RaisePropertyChanged("Content"); + } + } + } + + #endregion + + #region ContentId + + private string _contentId = null; + public string ContentId + { + get + { + if (_contentId == null) + { + var contentAsControl = _content as FrameworkElement; + if (contentAsControl != null && !string.IsNullOrWhiteSpace(contentAsControl.Name)) + return contentAsControl.Name; + } + return _contentId; + } + set + { + if (_contentId != value) + { + _contentId = value; + RaisePropertyChanged("ContentId"); + } + } + } + + #endregion + + #region IsSelected + + private bool _isSelected = false; + public bool IsSelected + { + get { return _isSelected; } + set + { + if (_isSelected != value) + { + bool oldValue = _isSelected; + RaisePropertyChanging("IsSelected"); + _isSelected = value; + var parentSelector = (Parent as ILayoutContentSelector); + if (parentSelector != null) + parentSelector.SelectedContentIndex = _isSelected ? parentSelector.IndexOf(this) : -1; + OnIsSelectedChanged(oldValue, value); + RaisePropertyChanged("IsSelected"); + } + } + } + + /// + /// Provides derived classes an opportunity to handle changes to the IsSelected property. + /// + protected virtual void OnIsSelectedChanged(bool oldValue, bool newValue) + { + if (IsSelectedChanged != null) + IsSelectedChanged(this, EventArgs.Empty); + } + + public event EventHandler IsSelectedChanged; + + #endregion + + #region IsActive + + [field: NonSerialized] + private bool _isActive = false; + [XmlIgnore] + public bool IsActive + { + get { return _isActive; } + set + { + if (_isActive != value) + { + RaisePropertyChanging("IsActive"); + bool oldValue = _isActive; + + _isActive = value; + + var root = Root; + if (root != null && _isActive) + root.ActiveContent = this; + + if (_isActive) + IsSelected = true; + + OnIsActiveChanged(oldValue, value); + RaisePropertyChanged("IsActive"); + } + } + } + + /// + /// Provides derived classes an opportunity to handle changes to the IsActive property. + /// + protected virtual void OnIsActiveChanged(bool oldValue, bool newValue) + { + if (newValue) + LastActivationTimeStamp = DateTime.Now; + + if (IsActiveChanged != null) + IsActiveChanged(this, EventArgs.Empty); + } + + public event EventHandler IsActiveChanged; + + #endregion + + #region IsLastFocusedDocument + + private bool _isLastFocusedDocument = false; + public bool IsLastFocusedDocument + { + get { return _isLastFocusedDocument; } + internal set + { + if (_isLastFocusedDocument != value) + { + RaisePropertyChanging("IsLastFocusedDocument"); + _isLastFocusedDocument = value; + RaisePropertyChanged("IsLastFocusedDocument"); + } + } + } + + #endregion + + #region PreviousContainer + + [field: NonSerialized] + private ILayoutContainer _previousContainer = null; + + [XmlIgnore] + ILayoutContainer ILayoutPreviousContainer.PreviousContainer + { + get { return _previousContainer; } + set + { + if (_previousContainer != value) + { + _previousContainer = value; + RaisePropertyChanged("PreviousContainer"); + + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if (paneSerializable != null && + paneSerializable.Id == null) + paneSerializable.Id = Guid.NewGuid().ToString(); + } + } + } + + protected ILayoutContainer PreviousContainer + { + get { return ((ILayoutPreviousContainer)this).PreviousContainer; } + set { ((ILayoutPreviousContainer)this).PreviousContainer = value; } + } + + [XmlIgnore] + string ILayoutPreviousContainer.PreviousContainerId + { + get; + set; + } + + protected string PreviousContainerId + { + get { return ((ILayoutPreviousContainer)this).PreviousContainerId; } + set { ((ILayoutPreviousContainer)this).PreviousContainerId = value; } + } + + #endregion + + #region PreviousContainerIndex + [field: NonSerialized] + private int _previousContainerIndex = -1; + [XmlIgnore] + public int PreviousContainerIndex + { + get { return _previousContainerIndex; } + set + { + if (_previousContainerIndex != value) + { + _previousContainerIndex = value; + RaisePropertyChanged("PreviousContainerIndex"); + } + } + } + + #endregion + + #region LastActivationTimeStamp + + private DateTime? _lastActivationTimeStamp = null; + public DateTime? LastActivationTimeStamp + { + get { return _lastActivationTimeStamp; } + set + { + if (_lastActivationTimeStamp != value) + { + _lastActivationTimeStamp = value; + RaisePropertyChanged("LastActivationTimeStamp"); + } + } + } + + #endregion + + protected override void OnParentChanging(ILayoutContainer oldValue, ILayoutContainer newValue) + { + var root = Root; + + if (oldValue != null) + IsSelected = false; + + //if (root != null && _isActive && newValue == null) + // root.ActiveContent = null; + + base.OnParentChanging(oldValue, newValue); + } + + protected override void OnParentChanged(ILayoutContainer oldValue, ILayoutContainer newValue) + { + if (IsSelected && Parent != null && Parent is ILayoutContentSelector) + { + var parentSelector = (Parent as ILayoutContentSelector); + parentSelector.SelectedContentIndex = parentSelector.IndexOf(this); + } + + //var root = Root; + //if (root != null && _isActive) + // root.ActiveContent = this; + + base.OnParentChanged(oldValue, newValue); + } + + /// + /// Test if the content can be closed + /// + /// + internal bool TestCanClose() + { + CancelEventArgs args = new CancelEventArgs(); + + OnClosing(args); + + if (args.Cancel) + return false; + + return true; + } + + /// + /// Close the content + /// + /// Please note that usually the anchorable is only hidden (not closed). By default when user click the X button it only hides the content. + public void Close() + { + var root = Root; + var parentAsContainer = Parent as ILayoutContainer; + parentAsContainer.RemoveChild(this); + + // Dispose if necessary + var content = this.Content as IDisposable; + if (content != null) + { + content.Dispose(); + } + + if (root != null) + root.CollectGarbage(); + + OnClosed(); + } + + /// + /// Event fired when the content is closed (i.e. removed definitely from the layout) + /// + public event EventHandler Closed; + + protected virtual void OnClosed() + { + if (Closed != null) + Closed(this, EventArgs.Empty); + } + + /// + /// Event fired when the content is about to be closed (i.e. removed definitely from the layout) + /// + /// Please note that LayoutAnchorable also can be hidden. Usually user hide anchorables when click the 'X' button. To completely close + /// an anchorable the user should click the 'Close' menu item from the context menu. When an LayoutAnchorable is hidden its visibility changes to false and + /// IsHidden property is set to true. + /// Hanlde the Hiding event for the LayoutAnchorable to cancel the hide operation. + public event EventHandler Closing; + + protected virtual void OnClosing(CancelEventArgs args) + { + if (Closing != null) + Closing(this, args); + } + + public System.Xml.Schema.XmlSchema GetSchema() + { + return null; + } + + public virtual void ReadXml(System.Xml.XmlReader reader) + { + if (reader.MoveToAttribute("Title")) + Title = reader.Value; + //if (reader.MoveToAttribute("IconSource")) + // IconSource = new Uri(reader.Value, UriKind.RelativeOrAbsolute); + + if (reader.MoveToAttribute("IsSelected")) + IsSelected = bool.Parse(reader.Value); + if (reader.MoveToAttribute("ContentId")) + ContentId = reader.Value; + if (reader.MoveToAttribute("IsLastFocusedDocument")) + IsLastFocusedDocument = bool.Parse(reader.Value); + if (reader.MoveToAttribute("PreviousContainerId")) + PreviousContainerId = reader.Value; + if (reader.MoveToAttribute("PreviousContainerIndex")) + PreviousContainerIndex = int.Parse(reader.Value); + + if (reader.MoveToAttribute("FloatingLeft")) + FloatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingTop")) + FloatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingWidth")) + FloatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingHeight")) + FloatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("IsMaximized")) + IsMaximized = bool.Parse(reader.Value); + if (reader.MoveToAttribute("CanClose")) + CanClose = bool.Parse(reader.Value); + if (reader.MoveToAttribute("CanFloat")) + CanFloat = bool.Parse(reader.Value); + if (reader.MoveToAttribute("LastActivationTimeStamp")) + LastActivationTimeStamp = DateTime.Parse(reader.Value, CultureInfo.InvariantCulture); + + reader.Read(); + } + + public virtual void WriteXml(System.Xml.XmlWriter writer) + { + if (!string.IsNullOrWhiteSpace(Title)) + writer.WriteAttributeString("Title", Title); + + //if (IconSource != null) + // writer.WriteAttributeString("IconSource", IconSource.ToString()); + + if (IsSelected) + writer.WriteAttributeString("IsSelected", IsSelected.ToString()); + + if (IsLastFocusedDocument) + writer.WriteAttributeString("IsLastFocusedDocument", IsLastFocusedDocument.ToString()); + + if (!string.IsNullOrWhiteSpace(ContentId)) + writer.WriteAttributeString("ContentId", ContentId); + + + if (ToolTip != null && ToolTip is string) + if (!string.IsNullOrWhiteSpace((string)ToolTip)) + writer.WriteAttributeString("ToolTip", (string)ToolTip); + + if (FloatingLeft != 0.0) + writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); + if (FloatingTop != 0.0) + writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); + if (FloatingWidth != 0.0) + writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); + if (FloatingHeight != 0.0) + writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); + + if (IsMaximized) + writer.WriteAttributeString("IsMaximized", IsMaximized.ToString()); + if (!CanClose) + writer.WriteAttributeString("CanClose", CanClose.ToString()); + if (!CanFloat) + writer.WriteAttributeString("CanFloat", CanFloat.ToString()); + + if (LastActivationTimeStamp != null) + writer.WriteAttributeString("LastActivationTimeStamp", LastActivationTimeStamp.Value.ToString(CultureInfo.InvariantCulture)); + + if (_previousContainer != null) + { + var paneSerializable = _previousContainer as ILayoutPaneSerializable; + if (paneSerializable != null) + { + writer.WriteAttributeString("PreviousContainerId", paneSerializable.Id); + writer.WriteAttributeString("PreviousContainerIndex", _previousContainerIndex.ToString()); + } + } + + } + + #region FloatingWidth + + private double _floatingWidth = 0.0; + public double FloatingWidth + { + get { return _floatingWidth; } + set + { + if (_floatingWidth != value) + { + RaisePropertyChanging("FloatingWidth"); + _floatingWidth = value; + RaisePropertyChanged("FloatingWidth"); + } + } + } + + #endregion + + #region FloatingHeight + + private double _floatingHeight = 0.0; + public double FloatingHeight + { + get { return _floatingHeight; } + set + { + if (_floatingHeight != value) + { + RaisePropertyChanging("FloatingHeight"); + _floatingHeight = value; + RaisePropertyChanged("FloatingHeight"); + } + } + } + + #endregion + + #region FloatingLeft + + private double _floatingLeft = 0.0; + public double FloatingLeft + { + get { return _floatingLeft; } + set + { + if (_floatingLeft != value) + { + RaisePropertyChanging("FloatingLeft"); + _floatingLeft = value; + RaisePropertyChanged("FloatingLeft"); + } + } + } + + #endregion + + #region FloatingTop + + private double _floatingTop = 0.0; + public double FloatingTop + { + get { return _floatingTop; } + set + { + if (_floatingTop != value) + { + RaisePropertyChanging("FloatingTop"); + _floatingTop = value; + RaisePropertyChanged("FloatingTop"); + } + } + } + + #endregion + + #region IsMaximized + + private bool _isMaximized = false; + public bool IsMaximized + { + get { return _isMaximized; } + set + { + if (_isMaximized != value) + { + RaisePropertyChanging("IsMaximized"); + _isMaximized = value; + RaisePropertyChanged("IsMaximized"); + } + } + } + + #endregion + + #region ToolTip + + private object _toolTip = null; + public object ToolTip + { + get { return _toolTip; } + set + { + if (_toolTip != value) + { + _toolTip = value; + RaisePropertyChanged("ToolTip"); + } + } + } + + #endregion + + public bool IsFloating + { + get { return this.FindParent() != null; } + } + + #region IconSource + + private ImageSource _iconSource = null; + public ImageSource IconSource + { + get { return _iconSource; } + set + { + if (_iconSource != value) + { + _iconSource = value; + RaisePropertyChanged("IconSource"); + } + } + } + + #endregion + + public int CompareTo(LayoutContent other) + { + var contentAsComparable = Content as IComparable; + if (contentAsComparable != null) + { + return contentAsComparable.CompareTo(other.Content); + } + + return string.Compare(Title, other.Title); + } + + /// + /// Float the content in a popup window + /// + public void Float() + { + if (PreviousContainer != null && + PreviousContainer.FindParent() != null) + { + + var currentContainer = Parent as ILayoutPane; + var currentContainerIndex = (currentContainer as ILayoutGroup).IndexOfChild(this); + var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + + if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) + previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); + else + previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); + + PreviousContainer = currentContainer; + PreviousContainerIndex = currentContainerIndex; + + IsSelected = true; + IsActive = true; + + Root.CollectGarbage(); + } + else + { + Root.Manager.StartDraggingFloatingWindowForContent(this, false); + + IsSelected = true; + IsActive = true; + } + + } + + /// + /// Dock the content as document + /// + public void DockAsDocument() + { + var root = Root as LayoutRoot; + if (root == null) + throw new InvalidOperationException(); + if (Parent is LayoutDocumentPane) + return; + + if (PreviousContainer is LayoutDocumentPane) + { + Dock(); + return; + } + + LayoutDocumentPane newParentPane; + if (root.LastFocusedDocument != null) + { + newParentPane = root.LastFocusedDocument.Parent as LayoutDocumentPane; + + // LastFocusedDocument's parent isn't always a DocumentPane for some reason. + // Attempt to find one when this happens. + if (newParentPane == null) + { + newParentPane = root.Descendents().OfType().FirstOrDefault(); + } + } + else + { + newParentPane = root.Descendents().OfType().FirstOrDefault(); + } + + if (newParentPane != null) + { + newParentPane.Children.Add(this); + root.CollectGarbage(); + } + + IsSelected = true; + IsActive = true; + } + + /// + /// Re-dock the content to its previous container + /// + public void Dock() + { + if (PreviousContainer != null) + { + var currentContainer = Parent as ILayoutContainer; + var currentContainerIndex = (currentContainer is ILayoutGroup) ? (currentContainer as ILayoutGroup).IndexOfChild(this) : -1; + var previousContainerAsLayoutGroup = PreviousContainer as ILayoutGroup; + + if (PreviousContainerIndex < previousContainerAsLayoutGroup.ChildrenCount) + previousContainerAsLayoutGroup.InsertChildAt(PreviousContainerIndex, this); + else + previousContainerAsLayoutGroup.InsertChildAt(previousContainerAsLayoutGroup.ChildrenCount, this); + + if (currentContainerIndex > -1) + { + PreviousContainer = currentContainer; + PreviousContainerIndex = currentContainerIndex; + } + else + { + PreviousContainer = null; + PreviousContainerIndex = 0; + } + + IsSelected = true; + IsActive = true; + } + else + { + InternalDock(); + } + + + Root.CollectGarbage(); + + } + + protected virtual void InternalDock() + { + + } + + + #region CanClose + + private bool _canClose = true; + public bool CanClose + { + get { return _canClose; } + set + { + if (_canClose != value) + { + _canClose = value; + RaisePropertyChanged("CanClose"); + } + } + } + + #endregion + + #region CanFloat + + private bool _canFloat = true; + public bool CanFloat + { + get { return _canFloat; } + set + { + if (_canFloat != value) + { + _canFloat = value; + RaisePropertyChanged("CanFloat"); + } + } + } + + #endregion + + #region CanDock + + private bool _canDock = true; + public bool CanDock + { + get { return _canDock; } + set + { + if (_canDock != value) + { + _canDock = value; + RaisePropertyChanged("CanDock"); + } + } + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs index ea7b201a..73baf589 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/LayoutPositionableGroup.cs @@ -23,274 +23,278 @@ using System.Globalization; namespace Xceed.Wpf.AvalonDock.Layout { - [Serializable] - public abstract class LayoutPositionableGroup : LayoutGroup, ILayoutPositionableElement, ILayoutPositionableElementWithActualSize where T : class, ILayoutElement - { - public LayoutPositionableGroup() - { } - - GridLength _dockWidth = new GridLength(1.0, GridUnitType.Star); - public GridLength DockWidth - { - get - { - return _dockWidth; - } - set - { - if (DockWidth != value) - { - RaisePropertyChanging("DockWidth"); - _dockWidth = value; - RaisePropertyChanged("DockWidth"); - - OnDockWidthChanged(); - } - } - } - - - protected virtual void OnDockWidthChanged() - { - - } - - GridLength _dockHeight = new GridLength(1.0, GridUnitType.Star); - public GridLength DockHeight - { - get - { - return _dockHeight; - } - set - { - if (DockHeight != value) - { - RaisePropertyChanging("DockHeight"); - _dockHeight = value; - RaisePropertyChanged("DockHeight"); - - OnDockHeightChanged(); - } - } - } - - protected virtual void OnDockHeightChanged() - { - - } - - - #region DockMinWidth - - private double _dockMinWidth = 25.0; - public double DockMinWidth - { - get { return _dockMinWidth; } - set - { - if (_dockMinWidth != value) - { - MathHelper.AssertIsPositiveOrZero(value); - RaisePropertyChanging("DockMinWidth"); - _dockMinWidth = value; - RaisePropertyChanged("DockMinWidth"); - } - } - } - - #endregion - - #region DockMinHeight - - private double _dockMinHeight = 25.0; - public double DockMinHeight - { - get { return _dockMinHeight; } - set - { - if (_dockMinHeight != value) - { - MathHelper.AssertIsPositiveOrZero(value); - RaisePropertyChanging("DockMinHeight"); - _dockMinHeight = value; - RaisePropertyChanged("DockMinHeight"); - } - } - } - - #endregion - - #region FloatingWidth - - private double _floatingWidth = 0.0; - public double FloatingWidth - { - get { return _floatingWidth; } - set - { - if (_floatingWidth != value) - { - RaisePropertyChanging("FloatingWidth"); - _floatingWidth = value; - RaisePropertyChanged("FloatingWidth"); - } - } - } - - #endregion - - #region FloatingHeight - - private double _floatingHeight = 0.0; - public double FloatingHeight - { - get { return _floatingHeight; } - set - { - if (_floatingHeight != value) - { - RaisePropertyChanging("FloatingHeight"); - _floatingHeight = value; - RaisePropertyChanged("FloatingHeight"); - } - } - } - - #endregion - - #region FloatingLeft - - private double _floatingLeft = 0.0; - public double FloatingLeft - { - get { return _floatingLeft; } - set - { - if (_floatingLeft != value) - { - RaisePropertyChanging("FloatingLeft"); - _floatingLeft = value; - RaisePropertyChanged("FloatingLeft"); - } - } - } - - #endregion - - #region FloatingTop - - private double _floatingTop = 0.0; - public double FloatingTop - { - get { return _floatingTop; } - set - { - if (_floatingTop != value) - { - RaisePropertyChanging("FloatingTop"); - _floatingTop = value; - RaisePropertyChanged("FloatingTop"); - } - } - } - - #endregion - - #region IsMaximized - - private bool _isMaximized = false; - public bool IsMaximized - { - get { return _isMaximized; } - set - { - if (_isMaximized != value) - { - _isMaximized = value; - RaisePropertyChanged("IsMaximized"); - } - } - } - - #endregion - - - [NonSerialized] - double _actualWidth; - double ILayoutPositionableElementWithActualSize.ActualWidth - { - get - { - return _actualWidth; - } - set - { - _actualWidth = value; - } - } - - [NonSerialized] - double _actualHeight; - double ILayoutPositionableElementWithActualSize.ActualHeight - { - get - { - return _actualHeight; - } - set - { - _actualHeight = value; - } - } - - public override void WriteXml(System.Xml.XmlWriter writer) - { - if (DockWidth.Value != 1.0 || !DockWidth.IsStar) - writer.WriteAttributeString("DockWidth", _gridLengthConverter.ConvertToInvariantString(DockWidth)); - if (DockHeight.Value != 1.0 || !DockHeight.IsStar) - writer.WriteAttributeString("DockHeight", _gridLengthConverter.ConvertToInvariantString(DockHeight)); - - if (DockMinWidth != 25.0) - writer.WriteAttributeString("DocMinWidth", DockMinWidth.ToString(CultureInfo.InvariantCulture)); - if (DockMinHeight != 25.0) - writer.WriteAttributeString("DockMinHeight", DockMinHeight.ToString(CultureInfo.InvariantCulture)); - - if (FloatingWidth != 0.0) - writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); - if (FloatingHeight != 0.0) - writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); - if (FloatingLeft != 0.0) - writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); - if (FloatingTop != 0.0) - writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); - - base.WriteXml(writer); - } - - static GridLengthConverter _gridLengthConverter = new GridLengthConverter(); - public override void ReadXml(System.Xml.XmlReader reader) - { - if (reader.MoveToAttribute("DockWidth")) - _dockWidth = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); - if (reader.MoveToAttribute("DockHeight")) - _dockHeight = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); - - if (reader.MoveToAttribute("DocMinWidth")) - _dockMinWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("DocMinHeight")) - _dockMinHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - - if (reader.MoveToAttribute("FloatingWidth")) - _floatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingHeight")) - _floatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingLeft")) - _floatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); - if (reader.MoveToAttribute("FloatingTop")) - _floatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); - - base.ReadXml(reader); - } - } + [Serializable] + public abstract class LayoutPositionableGroup : LayoutGroup, ILayoutPositionableElement, ILayoutPositionableElementWithActualSize where T : class, ILayoutElement + { + public LayoutPositionableGroup() + { } + + GridLength _dockWidth = new GridLength(1.0, GridUnitType.Star); + public GridLength DockWidth + { + get + { + return _dockWidth; + } + set + { + if (DockWidth != value) + { + RaisePropertyChanging("DockWidth"); + _dockWidth = value; + RaisePropertyChanged("DockWidth"); + + OnDockWidthChanged(); + } + } + } + + + protected virtual void OnDockWidthChanged() + { + + } + + GridLength _dockHeight = new GridLength(1.0, GridUnitType.Star); + public GridLength DockHeight + { + get + { + return _dockHeight; + } + set + { + if (DockHeight != value) + { + RaisePropertyChanging("DockHeight"); + _dockHeight = value; + RaisePropertyChanged("DockHeight"); + + OnDockHeightChanged(); + } + } + } + + protected virtual void OnDockHeightChanged() + { + + } + + + #region DockMinWidth + + private double _dockMinWidth = 25.0; + public double DockMinWidth + { + get { return _dockMinWidth; } + set + { + if (_dockMinWidth != value) + { + MathHelper.AssertIsPositiveOrZero(value); + RaisePropertyChanging("DockMinWidth"); + _dockMinWidth = value; + RaisePropertyChanged("DockMinWidth"); + } + } + } + + #endregion + + #region DockMinHeight + + private double _dockMinHeight = 25.0; + public double DockMinHeight + { + get { return _dockMinHeight; } + set + { + if (_dockMinHeight != value) + { + MathHelper.AssertIsPositiveOrZero(value); + RaisePropertyChanging("DockMinHeight"); + _dockMinHeight = value; + RaisePropertyChanged("DockMinHeight"); + } + } + } + + #endregion + + #region FloatingWidth + + private double _floatingWidth = 0.0; + public double FloatingWidth + { + get { return _floatingWidth; } + set + { + if (_floatingWidth != value) + { + RaisePropertyChanging("FloatingWidth"); + _floatingWidth = value; + RaisePropertyChanged("FloatingWidth"); + } + } + } + + #endregion + + #region FloatingHeight + + private double _floatingHeight = 0.0; + public double FloatingHeight + { + get { return _floatingHeight; } + set + { + if (_floatingHeight != value) + { + RaisePropertyChanging("FloatingHeight"); + _floatingHeight = value; + RaisePropertyChanged("FloatingHeight"); + } + } + } + + #endregion + + #region FloatingLeft + + private double _floatingLeft = 0.0; + public double FloatingLeft + { + get { return _floatingLeft; } + set + { + if (_floatingLeft != value) + { + RaisePropertyChanging("FloatingLeft"); + _floatingLeft = value; + RaisePropertyChanged("FloatingLeft"); + } + } + } + + #endregion + + #region FloatingTop + + private double _floatingTop = 0.0; + public double FloatingTop + { + get { return _floatingTop; } + set + { + if (_floatingTop != value) + { + RaisePropertyChanging("FloatingTop"); + _floatingTop = value; + RaisePropertyChanged("FloatingTop"); + } + } + } + + #endregion + + #region IsMaximized + + private bool _isMaximized = false; + public bool IsMaximized + { + get { return _isMaximized; } + set + { + if (_isMaximized != value) + { + _isMaximized = value; + RaisePropertyChanged("IsMaximized"); + } + } + } + + #endregion + + + [NonSerialized] + double _actualWidth; + double ILayoutPositionableElementWithActualSize.ActualWidth + { + get + { + return _actualWidth; + } + set + { + _actualWidth = value; + } + } + + [NonSerialized] + double _actualHeight; + double ILayoutPositionableElementWithActualSize.ActualHeight + { + get + { + return _actualHeight; + } + set + { + _actualHeight = value; + } + } + + public override void WriteXml(System.Xml.XmlWriter writer) + { + if (DockWidth.Value != 1.0 || !DockWidth.IsStar) + writer.WriteAttributeString("DockWidth", _gridLengthConverter.ConvertToInvariantString(DockWidth)); + if (DockHeight.Value != 1.0 || !DockHeight.IsStar) + writer.WriteAttributeString("DockHeight", _gridLengthConverter.ConvertToInvariantString(DockHeight)); + + if (DockMinWidth != 25.0) + writer.WriteAttributeString("DocMinWidth", DockMinWidth.ToString(CultureInfo.InvariantCulture)); + if (DockMinHeight != 25.0) + writer.WriteAttributeString("DockMinHeight", DockMinHeight.ToString(CultureInfo.InvariantCulture)); + + if (FloatingWidth != 0.0) + writer.WriteAttributeString("FloatingWidth", FloatingWidth.ToString(CultureInfo.InvariantCulture)); + if (FloatingHeight != 0.0) + writer.WriteAttributeString("FloatingHeight", FloatingHeight.ToString(CultureInfo.InvariantCulture)); + if (FloatingLeft != 0.0) + writer.WriteAttributeString("FloatingLeft", FloatingLeft.ToString(CultureInfo.InvariantCulture)); + if (FloatingTop != 0.0) + writer.WriteAttributeString("FloatingTop", FloatingTop.ToString(CultureInfo.InvariantCulture)); + if (IsMaximized) + writer.WriteAttributeString("IsMaximized", IsMaximized.ToString()); + + base.WriteXml(writer); + } + + static GridLengthConverter _gridLengthConverter = new GridLengthConverter(); + public override void ReadXml(System.Xml.XmlReader reader) + { + if (reader.MoveToAttribute("DockWidth")) + _dockWidth = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); + if (reader.MoveToAttribute("DockHeight")) + _dockHeight = (GridLength)_gridLengthConverter.ConvertFromInvariantString(reader.Value); + + if (reader.MoveToAttribute("DocMinWidth")) + _dockMinWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("DocMinHeight")) + _dockMinHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); + + if (reader.MoveToAttribute("FloatingWidth")) + _floatingWidth = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingHeight")) + _floatingHeight = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingLeft")) + _floatingLeft = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("FloatingTop")) + _floatingTop = double.Parse(reader.Value, CultureInfo.InvariantCulture); + if (reader.MoveToAttribute("IsMaximized")) + _isMaximized = bool.Parse(reader.Value); + + base.ReadXml(reader); + } + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs index 32f37c5c..5b9a2d66 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/LayoutSerializer.cs @@ -134,5 +134,34 @@ namespace Xceed.Wpf.AvalonDock.Layout.Serialization Manager.SuspendDocumentsSourceBinding = false; Manager.SuspendAnchorablesSourceBinding = false; } + + #region Virtual Serialize and Deserialize methods + + public virtual void Serialize(System.Xml.XmlWriter writer) + { } + public virtual void Serialize(System.IO.TextWriter writer) + { + } + public virtual void Serialize(System.IO.Stream stream) + { + } + public virtual void Serialize(string filepath) + { + } + public virtual void Deserialize(System.IO.Stream stream) + { + } + public virtual void Deserialize(System.IO.TextReader reader) + { + } + public virtual void Deserialize(System.Xml.XmlReader reader) + { + } + public virtual void Deserialize(string filepath) + { + } + + #endregion + } } diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs index a97e3277..16a01876 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Layout/Serialization/XmlLayoutSerializer.cs @@ -31,29 +31,29 @@ namespace Xceed.Wpf.AvalonDock.Layout.Serialization } - public void Serialize(System.Xml.XmlWriter writer) + public override void Serialize(System.Xml.XmlWriter writer) { var serializer = new XmlSerializer(typeof(LayoutRoot)); serializer.Serialize(writer, Manager.Layout); } - public void Serialize(System.IO.TextWriter writer) + public override void Serialize(System.IO.TextWriter writer) { var serializer = new XmlSerializer(typeof(LayoutRoot)); serializer.Serialize(writer, Manager.Layout); } - public void Serialize(System.IO.Stream stream) + public override void Serialize(System.IO.Stream stream) { var serializer = new XmlSerializer(typeof(LayoutRoot)); serializer.Serialize(stream, Manager.Layout); } - public void Serialize(string filepath) + public override void Serialize(string filepath) { using (var stream = new StreamWriter(filepath)) Serialize(stream); } - public void Deserialize(System.IO.Stream stream) + public override void Deserialize(System.IO.Stream stream) { try { @@ -69,7 +69,7 @@ namespace Xceed.Wpf.AvalonDock.Layout.Serialization } } - public void Deserialize(System.IO.TextReader reader) + public override void Deserialize(System.IO.TextReader reader) { try { @@ -85,7 +85,7 @@ namespace Xceed.Wpf.AvalonDock.Layout.Serialization } } - public void Deserialize(System.Xml.XmlReader reader) + public override void Deserialize(System.Xml.XmlReader reader) { try { @@ -101,7 +101,7 @@ namespace Xceed.Wpf.AvalonDock.Layout.Serialization } } - public void Deserialize(string filepath) + public override void Deserialize(string filepath) { using (var stream = new StreamReader(filepath)) Deserialize(stream); diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs index c9a8e19c..63f3b9a7 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Win32Helper.cs @@ -164,6 +164,11 @@ namespace Xceed.Wpf.AvalonDock internal const int WA_INACTIVE = 0x0000; + internal const int WM_SYSCOMMAND = 0x0112; + // These are the wParam of WM_SYSCOMMAND + internal const int SC_MAXIMIZE = 0xF030; + internal const int SC_RESTORE = 0xF120; + internal const int WM_CREATE = 0x0001; diff --git a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj index d45344fe..a39006f3 100644 --- a/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj +++ b/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.AvalonDock/Xceed.Wpf.AvalonDock.csproj @@ -21,7 +21,7 @@ full false bin\Debug\ - DEBUG + DEBUG;TRACE prompt 4 @@ -349,13 +349,12 @@ MSBuild:Compile - - \ No newline at end of file