예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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);
        }