private static void TabControl_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { TabControl sourceTabControl = (TabControl)sender; sourceTabControl.PreviewMouseLeftButtonUp -= TabTearOffBehavior.TabControl_PreviewMouseLeftButtonUp; sourceTabControl.PreviewMouseMove -= TabTearOffBehavior.TabControl_PreviewMouseMove; sourceTabControl.MouseLeave -= TabTearOffBehavior.TabControl_MouseLeaveOrLostCapture; sourceTabControl.LostMouseCapture -= TabTearOffBehavior.TabControl_MouseLeaveOrLostCapture; if (sourceTabControl.IsMouseCaptured) { TabItem tabItem = TabTearOffBehavior._activeTabItem; Point dragWindowLocation = new Point { X = TabTearOffBehavior._dragWindow.Left, Y = TabTearOffBehavior._dragWindow.Top }; sourceTabControl.ReleaseMouseCapture(); if (TabTearOffBehavior._adorner != null) { TabTearOffBehavior._adorner.Detach(); TabTearOffBehavior._adorner = null; } TabTearOffBehavior._dragWindow.Close(); TabTearOffBehavior._dragWindow = null; TabTearOffBehavior._activeTabItem = null; object item = sourceTabControl.ItemContainerGenerator.ItemFromContainer(tabItem); int sourceIndex = sourceTabControl.ItemContainerGenerator.IndexFromContainer(tabItem); Window dropWindow = TabTearOffBehavior.GetWindowMouseIsOver(e); TabControl targetTabControl; Panel targetPanel; ITabTearOffHandler targetHandler; if (dropWindow != null && TabTearOffBehavior.IsMouseInDropLocation(e, targetTabControl = TabTearOffBehavior.FindTargetTabControl(dropWindow, out targetHandler), targetPanel = ControlMethods.GetPanel(targetTabControl))) { int insertionIndex = TabTearOffBehavior.DetermineInsertionIndex(targetTabControl, e, targetPanel.GetOrientation()); if (!object.ReferenceEquals(sourceTabControl, targetTabControl)) { if (targetHandler.AllowTargetedDrop(item, sourceTabControl, sourceIndex, targetTabControl, insertionIndex)) { targetHandler.HandleTargetedDrop(item, sourceTabControl, sourceIndex, targetTabControl, insertionIndex); } } else if (sourceTabControl.Items.Count != 1 && insertionIndex != sourceIndex && targetHandler.AllowReorder(item, sourceTabControl, sourceIndex, insertionIndex)) { targetHandler.HandleReorder(item, sourceTabControl, sourceIndex, insertionIndex); } } else { ITabTearOffHandler sourceHandler = TabTearOffBehavior.GetHandler(sourceTabControl); if (sourceHandler.AllowTargetlessDrop(item, sourceTabControl, sourceIndex, dragWindowLocation)) { sourceHandler.HandleTargetlessDrop(item, sourceTabControl, sourceIndex, dragWindowLocation); } } } e.Handled = true; }
private static TabControl FindTargetTabControl(Window dropWindow, out ITabTearOffHandler handler) { handler = null; foreach (TabControl tabControl in dropWindow.GetVisualTreeDescendents <TabControl>()) { if ((handler = TabTearOffBehavior.GetHandler(tabControl)) != null) { return(tabControl); } } return(null); }
protected override void OnRender(DrawingContext drawingContext) { int insertionIndex = TabTearOffBehavior.DetermineInsertionIndex(this.AdornedElement, this._mouseEventArgs, this._orientation); ITabTearOffHandler handler = TabTearOffBehavior.GetHandler(this.AdornedElement); TabControl activeTabControl = TabTearOffBehavior._activeTabItem == null ? null : (TabControl)ItemsControl.ItemsControlFromItemContainer(TabTearOffBehavior._activeTabItem); if (activeTabControl == null || !this.AdornedElement.Equals(activeTabControl) && !handler.AllowTargetedDrop(activeTabControl.ItemContainerGenerator.ItemFromContainer(TabTearOffBehavior._activeTabItem), activeTabControl, activeTabControl.ItemContainerGenerator.IndexFromContainer(TabTearOffBehavior._activeTabItem), this.AdornedElement, insertionIndex) || this.AdornedElement.Equals(activeTabControl) && !handler.AllowReorder(activeTabControl.ItemContainerGenerator.ItemFromContainer(TabTearOffBehavior._activeTabItem), activeTabControl, activeTabControl.ItemContainerGenerator.IndexFromContainer(TabTearOffBehavior._activeTabItem), insertionIndex)) { return; } int index = Math.Min(insertionIndex, this.AdornedElement.Items.Count - 1); UIElement container; if ((container = (UIElement)this.AdornedElement.ItemContainerGenerator.ContainerFromIndex(index)) == null) { return; } Rect itemRect = new Rect(container.TranslatePoint(default(Point), this.AdornedElement), container.RenderSize); Point point1, point2; double rotation; if (this._orientation == Orientation.Vertical) { if (insertionIndex == this.AdornedElement.Items.Count) { itemRect.Y += container.RenderSize.Height; } point1 = new Point(itemRect.X - InsertionAdorner.Size, itemRect.Y); point2 = new Point(itemRect.Right + InsertionAdorner.Size, itemRect.Y); rotation = 0; } else { if (insertionIndex == this.AdornedElement.Items.Count) { itemRect.X += container.RenderSize.Width; } point1 = new Point(itemRect.X, itemRect.Y - InsertionAdorner.Size); point2 = new Point(itemRect.X, itemRect.Bottom + InsertionAdorner.Size); rotation = 90d; } InsertionAdorner.DrawArrow(drawingContext, point1, rotation); InsertionAdorner.DrawArrow(drawingContext, point2, 180d + rotation); }
/// <summary> /// Handles the PreviewMouseLeftButtonDown event of the TabControl. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.Windows.Input.MouseButtonEventArgs"/> instance containing the event data.</param> private static void TabControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { TabControl tabControl = (TabControl)sender; TabTearOffBehavior._activeTabItem = null; TabTearOffBehavior._dragStartPosition = default(Point); Point position = e.GetPosition(tabControl); HitTestResult result = VisualTreeHelper.HitTest(tabControl, position); if (result == null) { return; } TabItem tabItem = null; for (DependencyObject obj = result.VisualHit; obj != null; obj = VisualTreeHelper.GetParent(obj)) { ButtonBase button = obj as ButtonBase; if (button != null) { return; } if ((tabItem = obj as TabItem) != null) { break; } } if (tabItem == null || !tabControl.Equals(ItemsControl.ItemsControlFromItemContainer(tabItem)) || !TabTearOffBehavior.GetHandler(tabControl).IsDragAllowed(tabControl.ItemContainerGenerator.ItemFromContainer(tabItem), tabControl, tabControl.ItemContainerGenerator.IndexFromContainer(tabItem))) { return; } TabTearOffBehavior._activeTabItem = tabItem; TabTearOffBehavior._dragStartPosition = position; tabControl.PreviewMouseMove += TabTearOffBehavior.TabControl_PreviewMouseMove; tabControl.PreviewMouseLeftButtonUp += TabTearOffBehavior.TabControl_PreviewMouseLeftButtonUp; tabControl.MouseLeave += TabTearOffBehavior.TabControl_MouseLeaveOrLostCapture; tabControl.LostMouseCapture += TabTearOffBehavior.TabControl_MouseLeaveOrLostCapture; }