private void CaptionPanel_MouseMove(object sender, MouseEventArgs e) { if (!titleBar.IsMouseCaptured) { return; } var pos = e.GetPosition(titleBar); var dist = Math.Sqrt(Math.Pow(pos.X - dragStart.X, 2) + Math.Pow(pos.Y - dragStart.Y, 2)); if (dist > floatThreshold) { var args = new FloatEventArgs(this, null, e); titleBar.ReleaseMouseCapture(); FloatAllCommand?.TryExecute(args); } }
//internal command - OriginalSource is TabWellItem, Parameter is MouseEventArgs private void TabMouseMoveCommandExecuted(object sender, ExecutedRoutedEventArgs e) { var tab = (TabWellItem)e.OriginalSource; var mouseArgs = (MouseEventArgs)e.Parameter; if (!tab.IsMouseCaptured || !tab.IsLoaded) { return; } var item = ItemContainerGenerator.ItemFromContainer(tab); var index = Items.IndexOf(item); var pos = mouseArgs.GetPosition(tab); var offset = mouseArgs.GetPosition(this); var floatBounds = new Rect( pos.X - offset.X, -floatThreshold, this.ActualWidth, tab.ActualHeight + floatThreshold * 2 ); if (!floatBounds.Contains(pos)) { var args = new FloatEventArgs(this, tab, mouseArgs); tab.ReleaseMouseCapture(); DockManager.SetIsPinned(tab, false); FloatTabCommand?.TryExecute(args); return; } if (pos.X > 0 && pos.X < tab.ActualWidth) { swapThreshold = 0; } var isPinned = DockManager.GetIsPinned(tab); var grouped = Items.OfType <object>() .Select(i => ItemContainerGenerator.ContainerFromItem(i)) .Where(c => DockManager.GetIsPinned(c) == isPinned); var collection = ItemsSource as IList ?? Items as IList; if (pos.X < -swapThreshold && index > 0) { var prevTab = grouped.TakeWhile(c => c != tab).LastOrDefault() as FrameworkElement; if (prevTab != null) { swapThreshold = (int)Math.Ceiling(Math.Max(0, prevTab.ActualWidth - tab.ActualWidth)); floatThreshold = maxFloatThreshold; collection.Remove(item); collection.Insert(index - 1, item); tab = (TabWellItem)ItemContainerGenerator.ContainerFromIndex(index - 1); } } else if (pos.X > tab.ActualWidth + swapThreshold && index < Items.Count - 1) { var nextTab = grouped.SkipWhile(c => c != tab).Skip(1).FirstOrDefault() as FrameworkElement; if (nextTab != null) { swapThreshold = (int)Math.Ceiling(Math.Max(0, nextTab.ActualWidth - tab.ActualWidth)); floatThreshold = maxFloatThreshold; collection.Remove(item); collection.Insert(index + 1, item); tab = (TabWellItem)ItemContainerGenerator.ContainerFromIndex(index + 1); } } SelectedItem = item; tab.CaptureMouse(); }