我正在尝试在列表视图中执行拖放操作。问题是我选择带触摸的项目并移动它。首先,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;
}
}
}
}
答案 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;
}
}
}