public FloatingWindow(SplitTabsControl tabControl)
 {
     this.Content = tabControl;
     this.SplitTabsControl = tabControl;
     this.SizeChanged += this.OnSizeChanged;
     this.LocationChanged += this.OnLocationChanged;
 }
        // NOTE:  This method is static, because the actual SplitTabsControl that created the view may not be the one in which
        // that view lives at the time it is closed.  Being static forces the method to use the sender to obtain the appropriate
        // parent control.
        static void OnViewClosed(object sender, EventArgs e)
        {
            View view = sender as View;

            if (view == null)
            {
                return;
            }

            ActivatableTabItem    item             = ActivatableTabItem.GetTabItem(view);
            ActivatableTabControl tabControl       = item.TabControlParent;
            SplitTabsControl      splitTabsControl = tabControl.FindParent <SplitTabsControl>();
            TabNode node        = tabControl.TabNode;
            bool    switchFocus = tabControl.IsKeyboardFocusWithin;

            splitTabsControl.RemoveItemFromControl(item);

            if (switchFocus)
            {
                if (node.TabControl.SelectedItem is ActivatableTabItem)
                {
                    ((ActivatableTabItem)node.TabControl.SelectedItem).Focus();
                }
                else if (node == splitTabsControl.activeTabNode)
                {
                    // We just closed the last view in the active node.  Need to switch the active
                    // tab node to the last active one.
                    splitTabsControl.ActivateLastActiveTabNode();
                }
            }

            view.Closed -= OnViewClosed;
        }
 public FloatingWindow(SplitTabsControl tabControl)
 {
     this.Content          = tabControl;
     this.SplitTabsControl = tabControl;
     this.SizeChanged     += this.OnSizeChanged;
     this.LocationChanged += this.OnLocationChanged;
 }
        private void OnMouseLeftButtonDown(ActivatableTabItem item, MouseButtonEventArgs e)
        {
            e.MouseDevice.Capture(item);

            this.draggedItem            = item;
            this.sourceControl          = item.FindParent <ActivatableTabControl>();
            this.sourceSplitTabsControl = this.sourceControl.FindParent <SplitTabsControl>();

            this.offset    = e.GetPosition(item);
            this.preMoving = true;

            item.LostMouseCapture  += this.OnLostMouseCapture;
            item.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
            item.MouseMove         += this.OnMouseMove;
        }
        private void OnMouseLeftButtonDown(ActivatableTabItem item, MouseButtonEventArgs e)
        {
            e.MouseDevice.Capture(item);

            this.draggedItem = item;
            this.sourceControl = item.FindParent<ActivatableTabControl>();
            this.sourceSplitTabsControl = this.sourceControl.FindParent<SplitTabsControl>();

            this.offset = e.GetPosition(item);
            this.preMoving = true;

            item.LostMouseCapture += this.OnLostMouseCapture;
            item.MouseLeftButtonUp += this.OnMouseLeftButtonUp;
            item.MouseMove += this.OnMouseMove;
        }
        void MoveDraggedItemToNewControl(MouseButtonEventArgs e)
        {
            bool ctrlDown = Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl);

            if (ctrlDown || this.controlUnderCursor == null || this.hitTestSpot == null)
            {
                var  pos             = draggedItem.PointToScreenIndependent(e.GetPosition(draggedItem));
                var  originalContent = draggedItem.Content as FrameworkElement;
                Size size            = new Size(300, 200);

                if (originalContent != null)
                {
                    size = new Size(originalContent.ActualWidth, originalContent.ActualHeight);
                }

                var w = sourceSplitTabsControl.CreateFloatingHost();
                w.Left   = pos.X;
                w.Top    = pos.Y;
                w.Width  = size.Width;
                w.Height = size.Height;

                w.SplitTabsControl.Loaded += (s, e2) =>
                {
                    sourceSplitTabsControl.RemoveItemFromControl(this.draggedItem);
                    w.SplitTabsControl.AddItemToControl(this.draggedItem, w.SplitTabsControl.RootNode.TabControl, true);
                };
                w.Show();

                return;
            }

            SplitTabsControl destSplitTabsControl = this.controlUnderCursor.FindParent <SplitTabsControl>();

            if (sourceSplitTabsControl == null || destSplitTabsControl == null)
            {
                Debug.Fail("How does a tab control not live in a split tabs control parent?");
                return;
            }

            // Before removing the dragged item (which presumably has focus), set focus on the destination
            // tab control.  Otherwise we end up removing the focused element from the tree, which tends to
            // confuse the WPF focus manager.
            destSplitTabsControl.Focus();

            if (this.hitTestSpot.IsTabbed)
            {
                if (this.controlUnderCursor != this.sourceControl)
                {
                    sourceSplitTabsControl.RemoveItemFromControl(this.draggedItem);
                    destSplitTabsControl.AddItemToControl(this.draggedItem, this.controlUnderCursor, true);
                }

                return;
            }

            var newNode = destSplitTabsControl.SplitNode(this.hitTestSpot.DestinationNode, this.hitTestSpot.Dock);

            if (newNode != null)
            {
                sourceSplitTabsControl.RemoveItemFromControl(this.draggedItem);
                destSplitTabsControl.AddItemToControl(this.draggedItem, newNode.TabControl, true);
            }
        }