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 ITreeItem[] CollectSelectedItems() { List <ITreeItem> resultList = new List <ITreeItem>(); CollectSelectedItemsRecursion(this); return(resultList.ToArray()); void CollectSelectedItemsRecursion(ITreeItem item) { //Collect if (SelectedItemSet.Contains(item)) { resultList.Add(item); } //Recursion if (item is ITreeFolder) { foreach (ITreeItem childItem in ((ITreeFolder)item).ChildItemCollection) { CollectSelectedItemsRecursion(childItem); } } } }
private void ShiftSelectItems(ITreeItem startItem, ITreeItem endItem) { //Unselect SelectedItemSet.UnselectItems(); //Select SelectedItemSet.AddSelectedItem(startItem); ITreeItem[] items = CollectItems(); int startIndex = Array.IndexOf(items, startItem); int endIndex = Array.IndexOf(items, endItem); if (startIndex > endIndex) { int tempValue = endIndex; endIndex = startIndex; startIndex = tempValue; } for (int i = startIndex; i <= endIndex; ++i) { ITreeItem targetItem = items[i]; if (targetItem != startItem) { if (SelectedItemSet.Contains(targetItem)) { SelectedItemSet.RemoveSelectedItem(targetItem); } else { SelectedItemSet.AddSelectedItem(targetItem); } } } }
//Events private void ItemContext_MouseDown(object sender, MouseButtonEventArgs e) { if (e.ChangedButton != MouseButton.Left) { return; } isMousePressed = true; ITreeItem item = null; if (e.OriginalSource is FrameworkElement) { item = GetPressedItem((FrameworkElement)e.OriginalSource); } //Control 혹은 Shift를 누른 상태에선 Pressed에서 이벤트를 종료한다. if (item != null) { if (CanMultiSelect && Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) { //Control select if (SelectedItemSet.Contains(item)) { SelectedItemSet.RemoveSelectedItem(item); } else { SelectedItemSet.AddSelectedItem(item); } pressedItem = SelectedItemSet.Count > 0 ? SelectedItemSet.Last : null; } else if (CanMultiSelect && pressedItem != null && (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))) { //Shift select //pressedItem(Exclusive) ~ Item(Inclusive) 까지 선택한다. ShiftSelectItems(pressedItem, item); } else if (e.ClickCount == 2) { //Double click } else { //Normal select onMouseCapture = true; pressedItem = item; dragStartOffset = (float)e.GetPosition((IInputElement)item).Y; Mouse.Capture((IInputElement)sender, CaptureMode.Element); } } }
private void ItemContext_MouseMove(object sender, MouseEventArgs e) { if (isMousePressed && e.LeftButton != MouseButtonState.Pressed) { ItemContext_MouseUp(sender, null); return; } if (!onMouseCapture) { return; } Point cursorPos = e.GetPosition(ChildItemScrollViewer); Point absoluteCursorPos = e.GetPosition(ChildItemStackPanel); if (!onDragging) { float distance = Mathf.Abs(dragStartOffset - (float)e.GetPosition((IInputElement)pressedItem).Y); if (distance < 10) { return; } else { //Select item if (SelectedItemSet.Contains(pressedItem)) { SelectedItemSet.RemoveSelectedItem(pressedItem); SelectedItemSet.AddSelectedItem(pressedItem); } else { SelectedItemSet.SetSelectedItem(pressedItem); } //Start drag SetDraggingState(true); SetDraggingCursorVisible(true); CreateDraggingClone((FrameworkElement)pressedItem); } } //Dragging GetNodeTarget((float)cursorPos.Y); //Move draggingClone draggingClone.Margin = new Thickness(0d, cursorPos.Y - dragStartOffset, 0d, 0d); draggingClone.Opacity = 0.3d; }
//Notify public void NotifyItemRemoved(ITreeItem item) { SelectedItemSet.RemoveSelectedItem(item); }
private void Background_MouseDown(object sender, MouseButtonEventArgs e) { SelectedItemSet.UnselectItems(); }
private bool MoveSelectedItems(SelectedItemSet 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 ?? this; 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 ?? this; 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); }
private void InitMembers() { SelectedItemSet = new SelectedItemSet(); }