private void ItemContext_MouseUp(object sender, MouseButtonEventArgs e) { if ((e != null && e.ChangedButton != MouseButton.Left) || !onMouseCapture) { return; } isMousePressed = false; onMouseCapture = false; Mouse.Capture(null); if (!onDragging) { SelectedItemSet.SetSelectedItem(pressedItem); return; } if (e != null) { Point cursorPos = e.GetPosition(ChildItemScrollViewer); Point absoluteCursorPos = e.GetPosition(ChildItemStackPanel); NodeTarget target = GetNodeTarget((float)cursorPos.Y); MoveSelectedItems(SelectedItemSet, target); } RemoveDraggingClone(); SetDraggingState(false); SetDraggingCursorVisible(false); }
private NodeTarget GetNodeTarget(float cursorPosY) { NodeTarget target = null; float bottom = (float)ChildItemStackPanel.TranslatePoint(new Point(0f, ChildItemStackPanel.ActualHeight), ChildItemScrollViewer).Y; //최하단으로 이동 const float ClippingBias = 2f; if (cursorPosY > bottom - ClippingBias) { cursorPosY = (float)bottom - 1f; target = new NodeTarget(RootFolder, NodeDirection.InnerBottom); SetDraggingCursorPosition(bottom, 10f); } if (target == null) { //성능을 위해 탐색하면서 SetDraggingCursorPosition을 같이 호출합니다. ForeachItemsOptimize((ITreeItem item, ref bool breakFlag) => { if (item != pressedItem) { float top = (float)item.TranslatePoint(new Point(0, 0), ChildItemScrollViewer).Y; float diff = cursorPosY - top; float itemHeight = (float)item.ItemContext.ActualHeight; if (diff > 0f && diff < itemHeight) { target = new NodeTarget(item); if (item is ITreeFolder) { //Folder float sideEventHeight = itemHeight * SideEventRatio; float centerEventHeight = itemHeight * CenterEventRatio; if (diff < sideEventHeight) { //Top target.direction = NodeDirection.Top; SetDraggingCursorPosition(top, sideEventHeight); } else if (diff > itemHeight - sideEventHeight) { //Bottom target.direction = NodeDirection.Bottom; SetDraggingCursorPosition(top + itemHeight - sideEventHeight, sideEventHeight); } else { //Center target.direction = NodeDirection.InnerBottom; SetDraggingCursorPosition(top + sideEventHeight, centerEventHeight); } } else { //Item float sideEventHeight = itemHeight * 0.5f; if (diff < sideEventHeight) { //Top target.direction = NodeDirection.Top; SetDraggingCursorPosition(top, sideEventHeight); } else { //Bottom target.direction = NodeDirection.Bottom; SetDraggingCursorPosition(top + sideEventHeight, sideEventHeight); } } breakFlag = true; } } }); } SetDraggingCursorVisible(target != null); return(target); }
private bool MoveSelectedItems(SelectedListItemSet selectedItemSet, NodeTarget target) { if (target == null) { return(false); } ITreeFolder[] selectedFolders = selectedItemSet .Where(item => item is ITreeFolder) .Select(item => item as ITreeFolder).ToArray(); //자신 내부에 이동시도시 Reject foreach (ITreeFolder folder in selectedFolders) { if (folder == target.node) { return(false); } if (IsContainsChildRecursive(folder, target.node)) { MessageOccured?.Invoke("자신의 하위 폴더로 이동할 수 없습니다."); return(false); } } //정렬 ITreeItem[] sortedSelectedItems = CollectSelectedItems(); //이동 if (target.node is ITreeFolder && target.direction == NodeDirection.Bottom && ((ITreeFolder)target.node).ChildItemCollection.Count > 0) { target.direction = NodeDirection.InnerTop; } if (target.direction == NodeDirection.Bottom || target.direction == NodeDirection.InnerTop) { sortedSelectedItems = sortedSelectedItems.Reverse().ToArray(); } foreach (ITreeItem item in sortedSelectedItems) { ITreeFolder oldParent = item.ParentItem; ITreeFolder newParent = null; int index = -1; FrameworkElement uiItem = (FrameworkElement)item; if (oldParent != null) { oldParent.ChildItemCollection.Remove(item as UIElement); } else if (uiItem.Parent != null) { ((Panel)uiItem.Parent).Children.Remove(uiItem); } if (target.direction == NodeDirection.InnerTop) { //폴더 내부로 newParent = target.node as ITreeFolder; index = 0; } else if (target.direction == NodeDirection.InnerBottom) { //폴더 내부로 newParent = target.node as ITreeFolder; index = newParent.ChildItemCollection.Count; } else { //아이템 위아래로 newParent = target.node.ParentItem; index = newParent.ChildItemCollection.IndexOf(target.node as UIElement) + (target.direction == NodeDirection.Bottom ? 1 : 0); } if (AutoApplyItemMove) { newParent.ChildItemCollection.Insert(index, item as UIElement); } item.ParentItem = newParent; ItemMoved?.Invoke(item, oldParent, newParent, index); } return(true); }