/// <summary>
        /// Resets all fields.
        /// </summary>
        private void Reset()
        {
            Debug.Assert(Mouse.Captured == null);
            Debug.Assert(_borderDockIndicators == null);
            Debug.Assert(_paneDockIndicators == null);
            Debug.Assert(
                _dockStrategy == null || !_dockStrategy.DockControl.GetDockElements().OfType <DockTabItemProxy>().Any(),
                "All item proxies should have been removed.");

            _dockStrategy = null;
            _draggedItems.Clear();
            _activeItem           = null;
            _floatWindow          = null;
            _targetDockTabPane    = null;
            _layoutChanged        = false;
            _initialMousePosition = new Point(double.NaN, double.NaN);
            _dragDeltaExceeded    = false;
            _mouseOffset          = new Vector(double.NaN, double.NaN);
            _initialSize          = new Size(double.NaN, double.NaN);
            _canFloat             = true;
            _originalDockState    = DockState.Hide;
            _originalFloatWindow  = null;
            _originalFloatLeft    = 0;
            _originalFloatTop     = 0;
        }
Exemple #2
0
        /// <summary>
        /// Loads the docking layout.
        /// </summary>
        /// <param name="storedLayout">The stored layout.</param>
        /// <inheritdoc cref="DockSerializer.Load"/>
        public void LoadLayout(XElement storedLayout)
        {
            try
            {
                DockStrategy.Begin();

                var oldItems = Items.ToList();
                DockSerializer.Load(this, storedLayout);
                var newItems = Items.ToList();

                // Screen conduction for items closed in Load().
                foreach (var dockTabItem in oldItems.Except(newItems))
                {
                    // IActivatable
                    (dockTabItem as IActivatable)?.OnDeactivate(true);

                    // IScreen
                    var screen = dockTabItem as IScreen;
                    if (screen != null)
                    {
                        screen.Conductor = null;
                    }
                }
            }
            finally
            {
                DockStrategy.End();
            }
        }
Exemple #3
0
        ///// <summary>
        ///// Called when <see cref="IDockControl.ActiveDockTabPane"/> changed.
        ///// </summary>
        ///// <param name="sender">The sender.</param>
        ///// <param name="eventArgs">
        ///// The <see cref="PropertyChangedEventArgs"/> instance containing the event data.
        ///// </param>
        //private void OnActivePaneChanged(object sender, PropertyChangedEventArgs eventArgs)
        //{
        //}


        /// <summary>
        /// Called when <see cref="IDockControl.ActiveDockTabItem"/> changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="eventArgs">
        /// The <see cref="PropertyChangedEventArgs"/> instance containing the event data.
        /// </param>
        private void OnActiveItemChanged(object sender, PropertyChangedEventArgs eventArgs)
        {
            Debug.Assert(DockStrategy != null);
            Debug.Assert(DockStrategy.DockControl.ActiveDockTabItem == null || DockStrategy.DockControl.ActiveDockTabPane != null,
                         "IDockControl.ActiveDockTabPane needs to be set before IDockControl.ActiveDockTabItem.");
            Debug.Assert(DockStrategy.DockControl.ActiveDockTabPane == null || DockStrategy.DockControl.ActiveDockTabPane.SelectedItem == DockStrategy.DockControl.ActiveDockTabItem,
                         "IDockControl.ActiveDockTabPane.SelectedItem needs to match IDockControl.ActiveDockTabItem.");

            var dockTabPaneVM = DockStrategy.DockControl.ActiveDockTabPane;
            var dockTabItemVM = DockStrategy.DockControl.ActiveDockTabItem;

            if (dockTabPaneVM == null || dockTabItemVM == null)
            {
                CloseAutoHidePanes();
                return;
            }

            if (dockTabItemVM.DockState == DockState.Dock)
            {
                CloseAutoHidePanes();
            }
            else if (dockTabItemVM.DockState == DockState.Float)
            {
                CloseAutoHidePanes();
                var floatWindowVM = DockStrategy?.GetFloatWindow(dockTabItemVM);
                GetView(floatWindowVM)?.Activate();
            }
            else if (dockTabItemVM.DockState == DockState.AutoHide)
            {
                ShowAutoHidePane(dockTabPaneVM, dockTabItemVM);
            }

            GetView(dockTabItemVM)?.Activate();
        }
Exemple #4
0
        /// <inheritdoc/>
        public void ActivateItem(object item)
        {
            if (item == null)
            {
                throw new ArgumentNullException(nameof(item));
            }

            var dockTabItem = item as IDockTabItem;

            if (dockTabItem == null)
            {
                throw new ArgumentException("Item needs to implement IDockTabItem");
            }

            DockStrategy.Show(dockTabItem);


            // Validation
            var activatable = dockTabItem as IActivatable;

            if (activatable != null)
            {
                Debug.Assert(activatable.IsOpen);
                Debug.Assert(activatable.IsActive);
                Debug.Assert(GetItems(true).Contains(item));
            }

            var screen = dockTabItem as IScreen;

            if (screen != null)
            {
                Debug.Assert(screen.Conductor == this);
            }
        }
Exemple #5
0
        /// <inheritdoc/>
        public Task <bool> DeactivateItemAsync(object item, bool close)
        {
            var dockTabItem = item as IDockTabItem;

            if (dockTabItem == null ||
                !close ||   // Temporary deactivation is not supported.
                !DockStrategy.CanClose(dockTabItem))
            {
                return(TaskHelper.FromResult(false));
            }

            DockStrategy.Close(dockTabItem);


            // Validation
            var activatable = dockTabItem as IActivatable;

            if (activatable != null)
            {
                Debug.Assert(!activatable.IsActive);
                Debug.Assert(!activatable.IsOpen);
                Debug.Assert(!GetItems(false).Contains(item));
            }

            var screen = dockTabItem as IScreen;

            if (screen != null)
            {
                Debug.Assert(screen.Conductor == null);
            }


            return(TaskHelper.FromResult(true));
        }
Exemple #6
0
 /// <summary>
 /// Saves the docking layout.
 /// </summary>
 /// <param name="excludeNonPersistentItems">
 /// <see langword="true"/> to exclude non-persistent <see cref="IDockTabItem"/>s.
 /// <see langword="false"/> to store the layout of all (persistent and non-persistent)
 /// <see cref="IDockTabItem"/>s.
 /// </param>
 /// <returns>The <see cref="XElement"/> with the serialized layout.</returns>
 /// <inheritdoc cref="DockSerializer.Save(IDockControl,bool)"/>
 public XElement SaveLayout(bool excludeNonPersistentItems = false)
 {
     try
     {
         DockStrategy.Begin();
         return(DockSerializer.Save(this, excludeNonPersistentItems));
     }
     finally
     {
         DockStrategy.End();
     }
 }
Exemple #7
0
        public MainViewModel()
        {
            Themes = new List <string>
            {
                "Default",
                "System",
                "Light",
                "Gray",
                "Dark",
            };
            SelectedThemeIndex = 3;

            // Build dock layout directly.
            //var dockTabPaneViewModel = new DockTabPaneViewModel();
            //dockTabPaneViewModel.Items.Add(new SystemViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new SystemViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new DigitalRuneViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new DigitalRuneViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new PropertyGridViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new PropertyGridViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new ICSharpDevelopViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new ICSharpDevelopViewModel { DockState = DockState.Dock });

            //var dockAnchorPaneViewModel = new DockAnchorPaneViewModel
            //{
            //    ChildPane = dockTabPaneViewModel
            //};

            //DockControlViewModel = new DockControlViewModel(new DockStrategy())
            //{
            //    RootPane = dockAnchorPaneViewModel
            //};

            // Or use DockStrategy to do the same.
            var dockStrategy = new DockStrategy();

            DockControlViewModel = new DockControlViewModel(dockStrategy)
            {
                RootPane = new DockAnchorPaneViewModel(),
            };
            dockStrategy.Begin();
            dockStrategy.Dock(new SystemViewModel());
            dockStrategy.Dock(new SystemViewModel());
            dockStrategy.Dock(new DigitalRuneViewModel());
            dockStrategy.Dock(new DigitalRuneViewModel());
            dockStrategy.Dock(new PropertyGridViewModel());
            dockStrategy.Dock(new PropertyGridViewModel());
            dockStrategy.Dock(new ICSharpDevelopViewModel());
            dockStrategy.Dock(new ICSharpDevelopViewModel());
            dockStrategy.End();
        }
Exemple #8
0
        public MainViewModel()
        {
            Themes = new List<string>
            {
                "Default",
                "System",
                "Light",
                "Gray",
                "Dark",
            };
            SelectedThemeIndex = 3;

            // Build dock layout directly.
            //var dockTabPaneViewModel = new DockTabPaneViewModel();
            //dockTabPaneViewModel.Items.Add(new SystemViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new SystemViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new DigitalRuneViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new DigitalRuneViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new PropertyGridViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new PropertyGridViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new ICSharpDevelopViewModel { DockState = DockState.Dock });
            //dockTabPaneViewModel.Items.Add(new ICSharpDevelopViewModel { DockState = DockState.Dock });

            //var dockAnchorPaneViewModel = new DockAnchorPaneViewModel
            //{
            //    ChildPane = dockTabPaneViewModel
            //};

            //DockControlViewModel = new DockControlViewModel(new DockStrategy())
            //{
            //    RootPane = dockAnchorPaneViewModel
            //};

            // Or use DockStrategy to do the same.
            var dockStrategy = new DockStrategy();
            DockControlViewModel = new DockControlViewModel(dockStrategy)
            {
                RootPane = new DockAnchorPaneViewModel(),
            };
            dockStrategy.Begin();
            dockStrategy.Dock(new SystemViewModel());
            dockStrategy.Dock(new SystemViewModel());
            dockStrategy.Dock(new DigitalRuneViewModel());
            dockStrategy.Dock(new DigitalRuneViewModel());
            dockStrategy.Dock(new PropertyGridViewModel());
            dockStrategy.Dock(new PropertyGridViewModel());
            dockStrategy.Dock(new ICSharpDevelopViewModel());
            dockStrategy.Dock(new ICSharpDevelopViewModel());
            dockStrategy.End();
        }
Exemple #9
0
        internal void UpdateFloatWindows()
        {
            if (DockStrategy == null)
            {
                return;
            }

            var owner = Window.GetWindow(this);

            // Close obsolete FloatWindows.
            for (int i = _floatWindows.Count - 1; i >= 0; i--)
            {
                var floatWindow   = _floatWindows[i];
                var floatWindowVM = floatWindow.GetViewModel();
                if (floatWindowVM == null ||
                    !DockStrategy.DockControl.FloatWindows.Contains(floatWindowVM) ||
                    !DockStrategy.IsVisible(floatWindowVM))
                {
                    // ----- Close FloatWindow.
                    floatWindow.Close();
                    _floatWindows.RemoveAt(i);
                }
            }

            // Open new FloatWindows.
            for (int i = 0; i < DockStrategy.DockControl.FloatWindows.Count; i++)
            {
                var floatWindowVM = DockStrategy.DockControl.FloatWindows[i];
                if (DockStrategy.IsVisible(floatWindowVM) && GetView(floatWindowVM) == null)
                {
                    // ----- Open FloatWindow.

                    // Make sure that the floating window stays on the screen.
                    // At least 30 pixels must be visible.
                    const double safety       = 30;
                    double       screenLeft   = SystemParameters.VirtualScreenLeft;
                    double       screenTop    = SystemParameters.VirtualScreenTop;
                    double       screenRight  = screenLeft + SystemParameters.VirtualScreenWidth;
                    double       screenBottom = screenTop + SystemParameters.VirtualScreenHeight;
                    floatWindowVM.Left = Math.Min(Math.Max(floatWindowVM.Left, screenLeft), screenRight - safety);
                    floatWindowVM.Top  = Math.Min(Math.Max(floatWindowVM.Top, screenTop), screenBottom - safety);

                    var floatWindow = new FloatWindow(this)
                    {
                        DataContext = floatWindowVM,
                        Owner       = owner,
                    };

                    bool autoWidth  = Numeric.IsNaN(floatWindowVM.Width);
                    bool autoHeight = Numeric.IsNaN(floatWindowVM.Height);
                    if (autoWidth && autoHeight)
                    {
                        floatWindow.SizeToContent = SizeToContent.WidthAndHeight;
                    }
                    else if (autoWidth)
                    {
                        floatWindow.SizeToContent = SizeToContent.Width;
                    }
                    else if (autoHeight)
                    {
                        floatWindow.SizeToContent = SizeToContent.Height;
                    }
                    else
                    {
                        floatWindow.SizeToContent = SizeToContent.Manual;
                    }

                    floatWindow.SetBinding(ContentProperty, new Binding(nameof(IFloatWindow.RootPane)));
                    floatWindow.SetBinding(WidthProperty, new Binding(nameof(IFloatWindow.Width))
                    {
                        Mode = BindingMode.TwoWay
                    });
                    floatWindow.SetBinding(HeightProperty, new Binding(nameof(IFloatWindow.Height))
                    {
                        Mode = BindingMode.TwoWay
                    });
                    floatWindow.SetBinding(Window.LeftProperty, new Binding(nameof(IFloatWindow.Left))
                    {
                        Mode = BindingMode.TwoWay
                    });
                    floatWindow.SetBinding(Window.TopProperty, new Binding(nameof(IFloatWindow.Top))
                    {
                        Mode = BindingMode.TwoWay
                    });

                    floatWindow.Show();

                    // Bind WindowState after showing the window. Otherwise, it could be maximized
                    // on the wrong screen.
                    floatWindow.SetBinding(Window.WindowStateProperty, new Binding(nameof(IFloatWindow.WindowState))
                    {
                        Mode = BindingMode.TwoWay
                    });

                    _floatWindows.Add(floatWindow);
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DockControlViewModel" /> class with the
 /// specified <see cref="Docking.DockStrategy"/>.
 /// </summary>
 /// <param name="dockStrategy">The<see cref="Docking.DockStrategy"/>.</param>
 public DockControlViewModel(DockStrategy dockStrategy)
 {
     DockStrategy = dockStrategy;
 }
Exemple #11
0
        /// <summary>
        /// Starts a drag operation.
        /// </summary>
        /// <param name="floatWindow">The <see cref="FloatWindow"/> to be dragged.</param>
        /// <param name="dockTabPane">The <see cref="DockTabPane"/> to be dragged.</param>
        /// <param name="dockTabItem">The <see cref="DockTabItem"/> to be dragged.</param>
        /// <returns>
        /// <see langword="true" /> if the drag operation has been started; otherwise,
        /// <see langword="false" /> if the drag operation could not be started (e.g. because the
        /// mouse could not be captured).
        /// </returns>
        private bool BeginDrag(FloatWindow floatWindow, DockTabPane dockTabPane, DockTabItem dockTabItem)
        {
            _dockStrategy = _dockControl.GetViewModel()?.DockStrategy;
            if (_dockStrategy == null || _dockStrategy.DockControl.IsLocked)
            {
                Reset();
                return(false);
            }

            FrameworkElement element     = null;
            IDockTabPane     draggedPane = null;
            IDockTabItem     draggedItem = null;

            if (floatWindow != null)
            {
                // User is dragging a FloatWindow.
                // (Note: Dragging of FloatWindows with nested layouts is not supported.)
                draggedPane  = floatWindow.GetViewModel()?.RootPane as IDockTabPane;
                element      = floatWindow;
                _floatWindow = floatWindow;
                _initialSize = floatWindow.RenderSize;

                // Start dragging immediately.
                _dragDeltaExceeded = true;
            }
            else if (dockTabItem != null)
            {
                // User is dragging a DockTabItem in a DockTabPanel.
                draggedItem        = dockTabItem.GetViewModel();
                element            = dockTabItem;
                _targetDockTabPane = dockTabPane;
                _initialSize       = dockTabPane.RenderSize;

                // Start dragging when threshold is exceeded.
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);
                _dragDeltaExceeded    = false;
            }
            else if (dockTabPane != null)
            {
                // User is dragging a DockTabPane.
                draggedPane           = dockTabPane.GetViewModel();
                element               = dockTabPane;
                _initialSize          = dockTabPane.RenderSize;
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);

                // Start dragging when threshold is exceeded.
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);
                _dragDeltaExceeded    = false;
            }

            if (draggedPane == null && draggedItem == null)
            {
                Reset();
                return(false);
            }

            // When the user is dragging the FloatWindow, the mouse is captured by Win32 move window
            // loop. When dragging a DockTabPane or DockTabItem, the mouse needs to be
            // captured to receive mouse events.
            if (_floatWindow == null)
            {
                if (!_dockControl.CaptureMouse())
                {
                    // Failed to capture the mouse.
                    Reset();
                    return(false);
                }

                _dockControl.LostMouseCapture  += OnLostMouseCapture;
                _dockControl.MouseLeftButtonUp += OnMouseLeftButtonUp;
                _dockControl.MouseMove         += OnMouseMove;
                _dockControl.PreviewKeyDown    += OnPreviewKeyDown;
                if (_targetDockTabPane != null)
                {
                    _targetDockTabPane.PreviewKeyDown += OnPreviewKeyDown;
                }
            }

            _dockStrategy.Begin();

            if (draggedPane != null)
            {
                _dockStrategy.Activate(draggedPane);
                _activeItem = draggedPane.SelectedItem;
                foreach (var item in draggedPane.Items)
                {
                    if (item.DockState == draggedPane.DockState)
                    {
                        _draggedItems.Add(item);
                    }
                }
            }
            else
            {
                Debug.Assert(draggedItem != null);

                _dockStrategy.Activate(draggedItem);
                _activeItem = draggedItem;
                _draggedItems.Add(draggedItem);
            }

            Debug.Assert(_draggedItems.Count > 0);

            // Determine whether dragged items may end in a FloatWindow.
            _canFloat = CanFloat();

            // Store the mouse offset relative to the dragged element.
            _mouseOffset = (Vector)WindowsHelper.GetMousePosition(element);

            // Remember information needed for a rollback.
            ReplaceItemsWithProxies(draggedPane ?? _targetDockTabPane.GetViewModel());
            _originalDockState = _draggedItems[0].DockState;
            BackupFloatWindowPosition();

            // Override mouse cursors. (Mouse cursor should not change to caret over text editor.)
            Mouse.OverrideCursor = Cursors.Arrow;

            return(true);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DockControlViewModel" /> class with the
 /// specified <see cref="Docking.DockStrategy"/>.
 /// </summary>
 /// <param name="dockStrategy">The<see cref="Docking.DockStrategy"/>.</param>
 public DockControlViewModel(DockStrategy dockStrategy)
 {
     DockStrategy = dockStrategy;
 }
Exemple #13
0
        //--------------------------------------------------------------
        /// <summary>
        /// Resets all fields.
        /// </summary>
        private void Reset()
        {
            Debug.Assert(Mouse.Captured == null);
            Debug.Assert(_borderDockIndicators == null);
            Debug.Assert(_paneDockIndicators == null);
            Debug.Assert(
                _dockStrategy == null || !_dockStrategy.DockControl.GetDockElements().OfType<DockTabItemProxy>().Any(),
                "All item proxies should have been removed.");

            _dockStrategy = null;
            _draggedItems.Clear();
            _activeItem = null;
            _floatWindow = null;
            _targetDockTabPane = null;
            _layoutChanged = false;
            _initialMousePosition = new Point(double.NaN, double.NaN);
            _dragDeltaExceeded = false;
            _mouseOffset = new Vector(double.NaN, double.NaN);
            _initialSize = new Size(double.NaN, double.NaN);
            _canFloat = true;
            _originalDockState = DockState.Hide;
            _originalFloatWindow = null;
            _originalFloatLeft = 0;
            _originalFloatTop = 0;
        }
Exemple #14
0
        /// <summary>
        /// Starts a drag operation.
        /// </summary>
        /// <param name="floatWindow">The <see cref="FloatWindow"/> to be dragged.</param>
        /// <param name="dockTabPane">The <see cref="DockTabPane"/> to be dragged.</param>
        /// <param name="dockTabItem">The <see cref="DockTabItem"/> to be dragged.</param>
        /// <returns>
        /// <see langword="true" /> if the drag operation has been started; otherwise,
        /// <see langword="false" /> if the drag operation could not be started (e.g. because the
        /// mouse could not be captured).
        /// </returns>
        private bool BeginDrag(FloatWindow floatWindow, DockTabPane dockTabPane, DockTabItem dockTabItem)
        {
            _dockStrategy = _dockControl.GetViewModel()?.DockStrategy;
            if (_dockStrategy == null || _dockStrategy.DockControl.IsLocked)
            {
                Reset();
                return false;
            }

            FrameworkElement element = null;
            IDockTabPane draggedPane = null;
            IDockTabItem draggedItem = null;
            if (floatWindow != null)
            {
                // User is dragging a FloatWindow.
                // (Note: Dragging of FloatWindows with nested layouts is not supported.)
                draggedPane = floatWindow.GetViewModel()?.RootPane as IDockTabPane;
                element = floatWindow;
                _floatWindow = floatWindow;
                _initialSize = floatWindow.RenderSize;

                // Start dragging immediately.
                _dragDeltaExceeded = true;
            }
            else if (dockTabItem != null)
            {
                // User is dragging a DockTabItem in a DockTabPanel.
                draggedItem = dockTabItem.GetViewModel();
                element = dockTabItem;
                _targetDockTabPane = dockTabPane;
                _initialSize = dockTabPane.RenderSize;

                // Start dragging when threshold is exceeded.
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);
                _dragDeltaExceeded = false;
            }
            else if (dockTabPane != null)
            {
                // User is dragging a DockTabPane.
                draggedPane = dockTabPane.GetViewModel();
                element = dockTabPane;
                _initialSize = dockTabPane.RenderSize;
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);

                // Start dragging when threshold is exceeded.
                _initialMousePosition = WindowsHelper.GetMousePosition(_dockControl);
                _dragDeltaExceeded = false;
            }

            if (draggedPane == null && draggedItem == null)
            {
                Reset();
                return false;
            }

            // When the user is dragging the FloatWindow, the mouse is captured by Win32 move window
            // loop. When dragging a DockTabPane or DockTabItem, the mouse needs to be
            // captured to receive mouse events.
            if (_floatWindow == null)
            {
                if (!_dockControl.CaptureMouse())
                {
                    // Failed to capture the mouse.
                    Reset();
                    return false;
                }

                _dockControl.LostMouseCapture += OnLostMouseCapture;
                _dockControl.MouseLeftButtonUp += OnMouseLeftButtonUp;
                _dockControl.MouseMove += OnMouseMove;
                _dockControl.PreviewKeyDown += OnPreviewKeyDown;
                if (_targetDockTabPane != null)
                    _targetDockTabPane.PreviewKeyDown += OnPreviewKeyDown;
            }

            _dockStrategy.Begin();

            if (draggedPane != null)
            {
                _dockStrategy.Activate(draggedPane);
                _activeItem = draggedPane.SelectedItem;
                foreach (var item in draggedPane.Items)
                    if (item.DockState == draggedPane.DockState)
                        _draggedItems.Add(item);
            }
            else
            {
                Debug.Assert(draggedItem != null);

                _dockStrategy.Activate(draggedItem);
                _activeItem = draggedItem;
                _draggedItems.Add(draggedItem);
            }

            Debug.Assert(_draggedItems.Count > 0);

            // Determine whether dragged items may end in a FloatWindow.
            _canFloat = CanFloat();

            // Store the mouse offset relative to the dragged element.
            _mouseOffset = (Vector)WindowsHelper.GetMousePosition(element);

            // Remember information needed for a rollback.
            ReplaceItemsWithProxies(draggedPane ?? _targetDockTabPane.GetViewModel());
            _originalDockState = _draggedItems[0].DockState;
            BackupFloatWindowPosition();

            // Override mouse cursors. (Mouse cursor should not change to caret over text editor.)
            Mouse.OverrideCursor = Cursors.Arrow;

            return true;
        }