TouchMove事件的TouchEventArgs e.OrigionalSouce与TouchDown事件不同

时间:2017-11-27 20:18:45

标签: c# wpf xaml

我正在尝试在列表视图中执行拖放操作。问题是我选择带触摸的项目并移动它。首先,TouchDown事件执行正常。当我保持断点时,TouchEventArgs的e.OriginalSource是一个边框,我能够使用FindParent方法找到父类作为listviewitem。

问题是当调试器进入TouchMove事件时,TouchEventArgs,e.OriginalSource正在更改为ScrollViewer。我不知道它是如何改变的。因此,find parent返回null而不是listviewitem。请帮忙。

请在后面的代码中查看GlobalHandler事件中的TouchDown和TouchMove条件。

XAML:

<ListView
            Name="RunSetupListView"
            Grid.Row="0"
            Grid.Column="0"
            Grid.ColumnSpan="3"
            Style="{StaticResource RunSetupDisplayListViewStyle}"
            ItemsSource="{Binding RunSetupInfoList}"
            AlternationCount="100"
            LayoutUpdated="RunSetupListView_LayoutUpdated"
            PreviewMouseLeftButtonDown="GlobalHandler"
            PreviewTouchDown="GlobalHandler"
            PreviewMouseLeftButtonUp="GlobalHandler"
            PreviewTouchUp="GlobalHandler"
            PreviewMouseMove="GlobalHandler"
            PreviewTouchMove="GlobalHandler"
            DragEnter="RunSetupListView_DragEnter"
            DragOver="RunSetupListView_DragOver"
            Drop="RunSetupListView_Drop" 
            DragLeave="RunSetupListView_DragLeave"/>

背后的代码

private void GlobalHandler(object sender, InputEventArgs e)
        {
            if (e.RoutedEvent == PreviewMouseLeftButtonDownEvent)
            {
                var args = e as MouseButtonEventArgs;
                var listViewItem =
                        VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject)args.OriginalSource);
                if (listViewItem != null)
                {
                    SelectedDragItem = listViewItem;
                    // Log start point
                    StartPoint = args.GetPosition(null);
                }
            }

            if (e.RoutedEvent == PreviewTouchDownEvent)
            {
                var args = e as TouchEventArgs;
                var listViewItem =
                        VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject)args.OriginalSource);
                if (listViewItem != null)
                {
                    SelectedDragItem = listViewItem;
                    // Log start point
                    StartPoint = args.GetTouchPoint(null).Position;
                    IsScreenTouched = true;
                }
            }

            if (e.RoutedEvent == PreviewMouseLeftButtonUpEvent)
            {
                // Reest in case only a click occurs in the tree view WITHOUT a drag event
                StartPoint = null;
                SelectedDragItem = null;
            }

            if (e.RoutedEvent == PreviewTouchUpEvent)
            {
                // Reest in case only a click occurs in the tree view WITHOUT a drag event
                StartPoint = null;
                SelectedDragItem = null;
                IsScreenTouched = false;
            }

            if (e.RoutedEvent == PreviewMouseMoveEvent)
            {
                var args = e as MouseEventArgs;

                if (!(sender is ListView))
                    return;

                // only for left button down and if we received a mouse down
                // event in the listview... sometimes this event will still get processed
                // even if you click outside the listview but then drag the mouse into the listview
                if (args.LeftButton == MouseButtonState.Pressed && StartPoint != null && SelectedDragItem != null)
                {
                    var mousePos = args.GetPosition(null);
                    var diff = StartPoint.Value - mousePos;

                    // Once the drag has been dragged far enough... prevents a drag from happening
                    // from simply clicking the item
                    if ((Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance
                        || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) &&
                        !_inDragMode)
                    {
                        var listView = sender as ListView;

                        var listViewItem =
                            VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject)args.OriginalSource);

                        if (listViewItem == null)
                        {
                            return;
                        }

                        m_AdornerLayer = InitializeAdornerLayer(listViewItem, listView);
                        UpdateDragAdornerLocation(args.GetPosition(listView));
                        mousePoint = mousePos;
                        _inDragMode = true;
                        DataObject dragData = new DataObject(listViewItem.Content as DNA2RunInfoDisplay);
                        listView.CaptureMouse();
                        DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);

                        _inDragMode = false;
                        // Reset this here... the mouse up event DOES NOT get raised if we do a drag/drop effect
                        StartPoint = null;
                        SelectedDragItem = null;
                    }
                }
            }

            if (e.RoutedEvent == PreviewTouchMoveEvent)
            {
                var args = e as TouchEventArgs;

                if (!(sender is ListView))
                    return;


                // only for left button down and if we received a mouse down
                // event in the listview... sometimes this event will still get processed
                // even if you click outside the listview but then drag the mouse into the listview
                if (IsScreenTouched && StartPoint != null && SelectedDragItem != null)
                {
                    var mousePos = args.GetTouchPoint(null).Position;
                    var diff = StartPoint.Value - mousePos;

                    // Once the drag has been dragged far enough... prevents a drag from happening
                    // from simply clicking the item
                    if ((Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance
                        || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) &&
                        !_inDragMode)
                    {
                        var listView = sender as ListView;
          //This is the problem the args OriginalSource is a scroll viewer here
                        var listViewItem =
                            VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject)args.OriginalSource);

                        if (listViewItem == null)
                        {
                            return;
                        }

                        m_AdornerLayer = InitializeAdornerLayer(listViewItem, listView);
                        UpdateDragAdornerLocation(args.GetTouchPoint(listView).Position);
                        mousePoint = mousePos;
                        _inDragMode = true;
                        DataObject dragData = new DataObject(listViewItem.Content as DNA2RunInfoDisplay);
                        listView.CaptureTouch(args.TouchDevice);
                        DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);

                        _inDragMode = false;
                        IsScreenTouched = false;
                        // Reset this here... the mouse up event DOES NOT get raised if we do a drag/drop effect
                        StartPoint = null;
                        SelectedDragItem = null;
                    }
                }
            }
        }

1 个答案:

答案 0 :(得分:0)

如果有帮助,这里是完整的源代码。

private void DoDragandDrop(ListViewItem item, DataObject obj, DragDropEffects effect)
        {
            if ((item != null) && (obj != null))
            {
                DragDrop.DoDragDrop(item, obj, effect);
            }
        }

 private void GlobalHandler(object sender, InputEventArgs e)
        {
            Point? startPoint;
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewMouseLeftButtonDownEvent))
            {
                MouseButtonEventArgs args = e as MouseButtonEventArgs;
                ListViewItem item = VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject) args.OriginalSource);
                if (item != null)
                {
                    DNA2RunInfoDisplay content = item.Content as DNA2RunInfoDisplay;
                    if ((content != null) && (content.PlateIndex == -2147483648))
                    {
                        return;
                    }
                    this.SelectedDragItem = item;
                    this.StartPoint = new Point?(args.GetPosition(null));
                }
            }
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewTouchDownEvent))
            {
                ListView listView = sender as ListView;
                TouchEventArgs args2 = e as TouchEventArgs;
                object selectedItem = this.RunSetupListView.SelectedItem;
                ListViewItem itemToDrag = VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject) args2.OriginalSource);
                if (itemToDrag != null)
                {
                    itemToDrag.Focus();
                    this.SelectedDragItem = itemToDrag;
                    this.StartPoint = new Point?(args2.GetTouchPoint(null).Position);
                    this.m_AdornerLayer = this.InitializeAdornerLayer(itemToDrag, listView);
                    this.UpdateDragAdornerLocation(args2.GetTouchPoint(listView).Position);
                    if (this.SelectedDragItem.Content != BindingOperations.DisconnectedSource)
                    {
                        this.dataObject = new DataObject(this.SelectedDragItem.Content as DNA2RunInfoDisplay);
                    }
                    listView.CaptureTouch(args2.TouchDevice);
                }
            }
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewMouseLeftButtonUpEvent))
            {
                startPoint = null;
                this.StartPoint = startPoint;
                this.SelectedDragItem = null;
            }
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewTouchUpEvent))
            {
                startPoint = null;
                this.StartPoint = startPoint;
                this.SelectedDragItem = null;
                this.dataObject = null;
                if (this.m_DragAdorner != null)
                {
                    this.m_DragAdorner.Visibility = Visibility.Collapsed;
                }
            }
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewMouseMoveEvent))
            {
                MouseEventArgs args3 = e as MouseEventArgs;
                if (!(sender is ListView))
                {
                    return;
                }
                if ((args3.LeftButton == MouseButtonState.Pressed) && ((this.StartPoint != null) && (this.SelectedDragItem != null)))
                {
                    Point position = args3.GetPosition(null);
                    startPoint = this.StartPoint;
                    Vector vector = startPoint.Value - position;
                    if (((Math.Abs(vector.get_X()) > SystemParameters.MinimumHorizontalDragDistance) || (Math.Abs(vector.get_Y()) > SystemParameters.MinimumVerticalDragDistance)) && !this._inDragMode)
                    {
                        ListView listView = sender as ListView;
                        ListViewItem selectedDragItem = this.SelectedDragItem;
                        if (selectedDragItem == null)
                        {
                            return;
                        }
                        this.m_AdornerLayer = this.InitializeAdornerLayer(selectedDragItem, listView);
                        this.UpdateDragAdornerLocation(args3.GetPosition(listView));
                        this.mousePoint = position;
                        this._inDragMode = true;
                        listView.CaptureMouse();
                        DragDrop.DoDragDrop(selectedDragItem, new DataObject(selectedDragItem.Content as DNA2RunInfoDisplay), DragDropEffects.Move);
                        listView.ReleaseMouseCapture();
                        this._inDragMode = false;
                        startPoint = null;
                        this.StartPoint = startPoint;
                        this.SelectedDragItem = null;
                    }
                }
            }
            if (object.ReferenceEquals(e.RoutedEvent, UIElement.PreviewTouchMoveEvent))
            {
                Point position = (e as TouchEventArgs).GetTouchPoint(null).Position;
                startPoint = this.StartPoint;
                if ((startPoint == null) || (this.SelectedDragItem == null))
                {
                    if (this.m_DragAdorner != null)
                    {
                        this.m_DragAdorner.Visibility = Visibility.Collapsed;
                    }
                }
                else
                {
                    startPoint = this.StartPoint;
                    Point point3 = position;
                    if ((startPoint != null) ? ((startPoint != null) ? (startPoint.GetValueOrDefault() != point3) : false) : true)
                    {
                        startPoint = this.StartPoint;
                        Vector vector2 = startPoint.Value - position;
                        if (((Math.Abs(vector2.get_X()) > SystemParameters.MinimumHorizontalDragDistance) || (Math.Abs(vector2.get_Y()) > SystemParameters.MinimumVerticalDragDistance)) && (this.dataObject != null))
                        {
                            this.DoDragandDrop(this.SelectedDragItem, this.dataObject, DragDropEffects.Move);
                        }
                    }
                }
                this.SelectedDragItem = null;
                startPoint = null;
                this.StartPoint = startPoint;
            }
        }

        private void HandleDragEvent(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent(typeof(DNA2RunInfoDisplay)))
            {
                e.Effects = DragDropEffects.None;
                e.Handled = true;
            }
            else
            {
                DependencyObject originalSource = e.OriginalSource as DependencyObject;
                if (originalSource == null)
                {
                    e.Effects = DragDropEffects.None;
                    e.Handled = true;
                }
                else
                {
                    ListViewItem item = VisualTreeHelperUtils.FindParent<ListViewItem>(originalSource);
                    if (item == null)
                    {
                        e.Effects = DragDropEffects.None;
                        e.Handled = true;
                    }
                    else
                    {
                        if ((item.Content as DNA2RunInfoDisplay).RunState == DNA2RunStates.Unassigned)
                        {
                            e.Effects = DragDropEffects.None;
                        }
                        else
                        {
                            ListView relativeTo = sender as ListView;
                            if (relativeTo != null)
                            {
                                Point point = item.TransformToAncestor((Visual) relativeTo).Transform(new Point(0.0, 0.0));
                                this.UpdateDragAdornerLocation(new Point(point.get_X(), e.GetPosition(relativeTo).get_Y()));
                                this.m_DragAdorner.Visibility = Visibility.Visible;
                            }
                            e.Effects = e.AllowedEffects;
                        }
                        e.Handled = true;
                    }
                }
            }
        }
 private AdornerLayer InitializeAdornerLayer(ListViewItem itemToDrag, ListView listView)
        {
            VisualBrush brush = new VisualBrush(itemToDrag);
            this.m_DragAdorner = new BRDragAdornerWithVisualBrush(listView, itemToDrag.RenderSize, brush);
            AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(listView);
            adornerLayer.Add(this.m_DragAdorner);
            return adornerLayer;
        }

 private void RunSetupListView_DragEnter(object sender, DragEventArgs e)
        {
            this.HandleDragEvent(sender, e);
        }

        private void RunSetupListView_DragLeave(object sender, DragEventArgs e)
        {
            if (this.m_DragAdorner != null)
            {
                this.m_DragAdorner.Visibility = Visibility.Collapsed;
            }
        }

        private void RunSetupListView_DragOver(object sender, DragEventArgs e)
        {
            FrameworkElement depObj = sender as FrameworkElement;
            if (depObj != null)
            {
                ScrollViewer firstVisualChild = VisualTreeHelperUtils.GetFirstVisualChild<ScrollViewer>(depObj);
                if (firstVisualChild != null)
                {
                    double num = e.GetPosition(depObj).get_Y();
                    if (num < 30.0)
                    {
                        firstVisualChild.ScrollToVerticalOffset(firstVisualChild.VerticalOffset - 20.0);
                    }
                    else if (num > (depObj.ActualHeight - 30.0))
                    {
                        firstVisualChild.ScrollToVerticalOffset(firstVisualChild.VerticalOffset + 20.0);
                    }
                    this.HandleDragEvent(sender, e);
                }
            }
        }

        private void RunSetupListView_Drop(object sender, DragEventArgs e)
        {
            try
            {
                this._inDragMode = false;
                if (e.Data.GetDataPresent(typeof(DNA2RunInfoDisplay)))
                {
                    DNA2RunInfoDisplay data = (DNA2RunInfoDisplay) e.Data.GetData(typeof(DNA2RunInfoDisplay));
                    ListViewItem item = VisualTreeHelperUtils.FindParent<ListViewItem>((DependencyObject) e.OriginalSource);
                    if (item != null)
                    {
                        this.DNA2RunSetupVM.ChangeRunPriority(data, item.Content as DNA2RunInfoDisplay);
                        this.PropertyChanged(this, new PropertyChangedEventArgs("RunSetupInfoList"));
                    }
                }
            }
            finally
            {
                if (this.m_DragAdorner != null)
                {
                    this.m_DragAdorner.Visibility = Visibility.Collapsed;
                }
            }
        }