Exemplo n.º 1
0
        /// <summary>
        /// Clear local variable and set selected items wh when mouse button up
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void DoMouseButtonUp(object sender, MouseButtonEventArgs e)
        {
            var elementPosition = e.GetPosition((IInputElement)sender);

            if ((sender is TabControl) && !HitTestUtilities.HitTest4Type <TabPanel>(sender, elementPosition))
            {
                m_DragInfo         = null;
                m_ClickSupressItem = null;
                return;
            }

            var dragInfo = m_DragInfo;

            // If we prevented the control's default selection handling in DragSource_PreviewMouseLeftButtonDown
            // by setting 'e.Handled = true' and a drag was not initiated, manually set the selection here.
            if (sender is ItemsControl itemsControl && dragInfo != null && m_ClickSupressItem != null && m_ClickSupressItem == dragInfo.SourceItem)
            {
                if ((Keyboard.Modifiers & ModifierKeys.Control) != 0)
                {
                    itemsControl.SetItemSelected(dragInfo.SourceItem, false);
                }
                else if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0)
                {
                    itemsControl.SetSelectedItem(dragInfo.SourceItem);
                }
            }

            m_DragInfo         = null;
            m_ClickSupressItem = null;
        }
Exemplo n.º 2
0
        /// <summary>
        /// Gets the drag handler from the drag info or from the sender, if the drag info is null
        /// </summary>
        /// <param name="dragInfo">the drag info object</param>
        /// <param name="sender">the sender from an event, e.g. mouse down, mouse move</param>
        /// <returns></returns>
        private static IDragSource TryGetDragHandler(DragInfo dragInfo, UIElement sender)
        {
            IDragSource dragHandler = null;

            if (dragInfo?.VisualSource != null)
            {
                dragHandler = GetDragHandler(dragInfo.VisualSource);
            }

            if (dragHandler == null && sender != null)
            {
                dragHandler = GetDragHandler(sender);
            }

            return(dragHandler ?? DefaultDragHandler);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the DropInfo class.
        /// <param name="sender">The sender of the drag event.</param>
        /// <param name="e">The drag event.</param>
        /// <param name="dragInfo">Information about the source of the drag, if the drag came from within the framework.</param>
        /// <param name="eventType">The type of the underlying event (tunneled or bubbled).</param>
        /// </summary>
        public DropInfo(object sender, DragEventArgs e, [CanBeNull] DragInfo dragInfo, EventType eventType)
        {
            DragInfo  = dragInfo;
            KeyStates = e.KeyStates;
            EventType = eventType;
            var dataFormat = dragInfo?.DataFormat;

            Data = dataFormat != null && e.Data.GetDataPresent(dataFormat.Name) ? e.Data.GetData(dataFormat.Name) : e.Data;

            VisualTarget = sender as UIElement;
            // if there is no drop target, find another
            if (!VisualTarget.IsDropTarget())
            {
                // try to find next element
                var element = VisualTarget.TryGetNextAncestorDropTargetElement();
                if (element != null)
                {
                    VisualTarget = element;
                }
            }

            // try find ScrollViewer
            var dropTargetScrollViewer = DragDrop.GetDropTargetScrollViewer(VisualTarget);

            if (dropTargetScrollViewer != null)
            {
                TargetScrollViewer = dropTargetScrollViewer;
            }
            else if (VisualTarget is TabControl)
            {
                var tabPanel = VisualTarget.FindVisualChild <TabPanel>();
                TargetScrollViewer = tabPanel?.FindVisualParent <ScrollViewer>();
            }
            else
            {
                TargetScrollViewer = VisualTarget?.FindVisualChild <ScrollViewer>();
            }

            TargetScrollingMode = VisualTarget != null?DragDrop.GetDropScrollingMode(VisualTarget) : ScrollingMode.Both;

            // visual target can be null, so give us a point...
            DropPosition = VisualTarget != null?e.GetPosition(VisualTarget) : new Point();

            if (VisualTarget is TabControl)
            {
                if (!HitTestUtilities.HitTest4Type <TabPanel>(VisualTarget, DropPosition))
                {
                    return;
                }
            }

            if (VisualTarget is ItemsControl itemsControl)
            {
                //System.Diagnostics.Debug.WriteLine(">>> Name = {0}", itemsControl.Name);
                // get item under the mouse
                item = itemsControl.GetItemContainerAt(DropPosition);
                var directlyOverItem = item != null;

                TargetGroup               = itemsControl.FindGroup(DropPosition);
                VisualTargetOrientation   = itemsControl.GetItemsPanelOrientation();
                VisualTargetFlowDirection = itemsControl.GetItemsPanelFlowDirection();

                if (item == null)
                {
                    // ok, no item found, so maybe we can found an item at top, left, right or bottom
                    item             = itemsControl.GetItemContainerAt(DropPosition, VisualTargetOrientation);
                    directlyOverItem = DropPosition.DirectlyOverElement(item, itemsControl);
                }

                if (item == null && TargetGroup != null && TargetGroup.IsBottomLevel)
                {
                    var itemData = TargetGroup.Items.FirstOrDefault();
                    if (itemData != null)
                    {
                        item             = itemsControl.ItemContainerGenerator.ContainerFromItem(itemData) as UIElement;
                        directlyOverItem = DropPosition.DirectlyOverElement(item, itemsControl);
                    }
                }

                if (item != null)
                {
                    itemParent = ItemsControl.ItemsControlFromItemContainer(item);
                    VisualTargetOrientation   = itemParent.GetItemsPanelOrientation();
                    VisualTargetFlowDirection = itemParent.GetItemsPanelFlowDirection();

                    InsertIndex      = itemParent.ItemContainerGenerator.IndexFromContainer(item);
                    TargetCollection = itemParent.ItemsSource ?? itemParent.Items;

                    var tvItem = item as TreeViewItem;

                    if (directlyOverItem || tvItem != null)
                    {
                        VisualTargetItem = item;
                        TargetItem       = itemParent.ItemContainerGenerator.ItemFromContainer(item);
                    }

                    var expandedTVItem = tvItem != null && tvItem.HasHeader && tvItem.HasItems && tvItem.IsExpanded;
                    var itemRenderSize = expandedTVItem ? tvItem.GetHeaderSize() : item.RenderSize;

                    if (VisualTargetOrientation == Orientation.Vertical)
                    {
                        // Get the current position relative to the items container
                        var currentYPos = e.GetPosition(item).Y;
                        // Get items container height
                        var targetHeight = itemRenderSize.Height;

                        var topGap    = targetHeight * 0.25;
                        var bottomGap = targetHeight * 0.75;
                        if (currentYPos > targetHeight / 2)
                        {
                            // If items control is tree viewer
                            if (expandedTVItem && (currentYPos < topGap || currentYPos > bottomGap))
                            {
                                VisualTargetItem = tvItem.ItemContainerGenerator.ContainerFromIndex(0) as UIElement;
                                TargetItem       = VisualTargetItem != null?tvItem.ItemContainerGenerator.ItemFromContainer(VisualTargetItem) : null;

                                TargetCollection = tvItem.ItemsSource ?? tvItem.Items;
                                InsertIndex      = 0;
                                InsertPosition   = RelativeInsertPosition.BeforeTargetItem;
                            }
                            else
                            {
                                InsertIndex++;
                                InsertPosition = RelativeInsertPosition.AfterTargetItem;
                            }
                        }
                        else
                        {
                            InsertPosition = RelativeInsertPosition.BeforeTargetItem;
                        }

                        if (currentYPos > topGap && currentYPos < bottomGap)
                        {
                            if (tvItem != null)
                            {
                                TargetCollection = tvItem.ItemsSource ?? tvItem.Items;
                                InsertIndex      = TargetCollection != null?TargetCollection.OfType <object>().Count() : 0;
                            }
                            InsertPosition |= RelativeInsertPosition.TargetItemCenter;
                        }
                        //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, Y={2}, Item={3}", InsertPosition, InsertIndex, currentYPos, item);
                    }
                    else
                    {
                        var currentXPos = e.GetPosition(item).X;
                        var targetWidth = itemRenderSize.Width;

                        if (VisualTargetFlowDirection == FlowDirection.RightToLeft)
                        {
                            if (currentXPos > targetWidth / 2)
                            {
                                InsertPosition = RelativeInsertPosition.BeforeTargetItem;
                            }
                            else
                            {
                                InsertIndex++;
                                InsertPosition = RelativeInsertPosition.AfterTargetItem;
                            }
                        }
                        else if (VisualTargetFlowDirection == FlowDirection.LeftToRight)
                        {
                            if (currentXPos > targetWidth / 2)
                            {
                                InsertIndex++;
                                InsertPosition = RelativeInsertPosition.AfterTargetItem;
                            }
                            else
                            {
                                InsertPosition = RelativeInsertPosition.BeforeTargetItem;
                            }
                        }

                        if (currentXPos > targetWidth * 0.25 && currentXPos < targetWidth * 0.75)
                        {
                            if (tvItem != null)
                            {
                                TargetCollection = tvItem.ItemsSource ?? tvItem.Items;
                                InsertIndex      = TargetCollection != null?TargetCollection.OfType <object>().Count() : 0;
                            }
                            InsertPosition |= RelativeInsertPosition.TargetItemCenter;
                        }
                        //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, idx={1}, X={2}, Item={3}", InsertPosition, InsertIndex, currentXPos, item);
                    }
                }
                else
                {
                    TargetCollection = itemsControl.ItemsSource ?? itemsControl.Items;
                    InsertIndex      = itemsControl.Items.Count;
                    //System.Diagnostics.Debug.WriteLine("==> DropInfo: pos={0}, item=NULL, idx={1}", InsertPosition, InsertIndex);
                }
            }
            else
            {
                VisualTargetItem = VisualTarget;
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Set base drag info when mouse left button down
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void DoMouseButtonDown(object sender, MouseButtonEventArgs e)
        {
            m_DragInfo = null;

            // Gets the position of the mouse relative to source control
            var elementPosition = e.GetPosition((IInputElement)sender);

            // Ignore the click if clickCount != 1 or the user has clicked on a scrollbar or the control while editing.
            if (e.ClickCount != 1 ||
                (sender as UIElement).IsDragSourceIgnored() ||
                (e.Source as UIElement).IsDragSourceIgnored() ||
                (e.OriginalSource as UIElement).IsDragSourceIgnored()
                // Ignore TabControl's content presenter
                || (sender is TabControl) && !HitTestUtilities.HitTest4Type <TabPanel>(sender, elementPosition)
                // Ignore scroll bar
                || HitTestUtilities.HitTest4Type <RangeBase>(sender, elementPosition)
                // Ignore the control while editing.
                || HitTestUtilities.HitTest4Type <TextBoxBase>(sender, elementPosition) ||
                HitTestUtilities.HitTest4Type <PasswordBox>(sender, elementPosition) ||
                HitTestUtilities.HitTest4Type <ComboBox>(sender, elementPosition)
                // Ignore grid column header
                || HitTestUtilities.HitTest4GridViewColumnHeader(sender, elementPosition)
                // Ignore user reordering DataGrid columns and drag row header gripper to chang row header height
                || HitTestUtilities.HitTest4DataGridTypes(sender, elementPosition) ||
                HitTestUtilities.IsNotPartOfSender(sender, e))
            {
                return;
            }

            var dragInfo = new DragInfo(sender, e);

            if (dragInfo.VisualSource is ItemsControl control && control.CanSelectMultipleItems())
            {
                control.Focus();
            }

            if (dragInfo.VisualSourceItem == null)
            {
                return;
            }

            var dragHandler = TryGetDragHandler(dragInfo, sender as UIElement);

            if (!dragHandler.CanStartDrag(dragInfo))
            {
                return;
            }

            // If the sender is a list box that allows multiple selections, ensure that clicking on an
            // already selected item does not change the selection(didn't click a shift key or control key at the same time),
            // otherwise dragging multiple items is made impossible.
            if ((Keyboard.Modifiers & ModifierKeys.Shift) == 0 && (Keyboard.Modifiers & ModifierKeys.Control) == 0 && dragInfo.VisualSourceItem != null && sender is ItemsControl itemsControl && itemsControl.CanSelectMultipleItems())
            {
                var selectedItems = itemsControl.GetSelectedItems().OfType <object>().ToList();

                // we haven't pressed control key and shift key, set clicked current item
                if (selectedItems.Count > 1 && selectedItems.Contains(dragInfo.SourceItem))
                {
                    m_ClickSupressItem = dragInfo.SourceItem;
                    e.Handled          = true;
                }
            }

            m_DragInfo = dragInfo;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Raise on mouse move at source ItemsControl
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private static void DragSourceOnMouseMove(object sender, MouseEventArgs e)
        {
            var dragInfo = m_DragInfo;

            // if we not release the mouse button while we moving our mouse...
            if (dragInfo != null && !m_DragInProgress)
            {
                // the start from the source
                var dragStart = dragInfo.DragStartPosition;

                // do nothing if mouse left/right button is released or the pointer is captured
                if (dragInfo.MouseButton == MouseButton.Left && e.LeftButton == MouseButtonState.Released)
                {
                    m_DragInfo = null;
                    return;
                }
                if (GetCanDragWithMouseRightButton(dragInfo.VisualSource) && dragInfo.MouseButton == MouseButton.Right && e.RightButton == MouseButtonState.Released)
                {
                    m_DragInfo = null;
                    return;
                }

                // current mouse position
                var position = e.GetPosition((IInputElement)sender);

                // prevent selection changing while drag operation
                dragInfo.VisualSource?.ReleaseMouseCapture();

                // only if the sender is the source control and the mouse point differs from an offset
                if (dragInfo.VisualSource == sender &&
                    (Math.Abs(position.X - dragStart.X) > GetMinimumHorizontalDragDistance(dragInfo.VisualSource) ||
                     Math.Abs(position.Y - dragStart.Y) > GetMinimumVerticalDragDistance(dragInfo.VisualSource)))
                {
                    // Ensure SourceItems is latest selected items
                    dragInfo.RefreshSelectedItems(sender, e);

                    var dragHandler = TryGetDragHandler(dragInfo, sender as UIElement);
                    if (dragHandler.CanStartDrag(dragInfo))
                    {
                        dragHandler.StartDrag(dragInfo);

                        if (dragInfo.Effects != DragDropEffects.None)
                        {
                            var dataObject = dragInfo.DataObject;

                            if (dataObject == null)
                            {
                                if (dragInfo.Data == null)
                                {
                                    // it's bad if the Data is null, cause the DataObject constructor will raise an ArgumentNullException
                                    m_DragInfo = null; // maybe not necessary or should not set here to null
                                    return;
                                }
                                dataObject = new DataObject(dragInfo.DataFormat.Name, dragInfo.Data);
                            }

                            try
                            {
                                m_DragInProgress = true;
                                var dragDropHandler = dragInfo.DragDropHandler ?? System.Windows.DragDrop.DoDragDrop;
                                var dragDropEffects = dragDropHandler(dragInfo.VisualSource, dataObject, dragInfo.Effects);
                                if (dragDropEffects == DragDropEffects.None)
                                {
                                    dragHandler.DragCancelled();
                                }
                                dragHandler.DragDropOperationFinished(dragDropEffects, dragInfo);
                            }
                            catch (Exception ex)
                            {
                                if (!dragHandler.TryCatchOccurredException(ex))
                                {
                                    throw;
                                }
                            }
                            finally
                            {
                                m_DragInProgress = false;
                                m_DragInfo       = null;
                            }
                        }
                    }
                }
            }
        }