WPF ListView数据绑定拖放自动滚动 [英] WPF ListView Databound Drag/Drop Auto Scroll
问题描述
我一直在使用Bea的解决方案 here ,找到它很有帮助。现在我遇到的问题是当我将项目拖放到另一个ListView控件中时,我想在拖动(将项目从索引30移动到索引1)期间向上/向下滚动,但没有发生。我必须拖动到ListView中的视觉项目的顶部,手动向上滚动,然后再次拖动,最终以我想要的位置结束。这不是非常用户友好。
I've been working with Bea's solution here for a while and finding it very helpful. Problem now I'm having is when I drag-n-drop items within or to another ListView control and I want to scroll up/down "during" the drag (moving an item from index 30 to index 1), it's not happening. I would have to drag to the top of the visual items in the ListView, manually scroll up, then drag again, eventually ending at the position I want. This isn't very user friendly.
现在我发现了我想要测试哪个项目被拖动的函数(DragDropHelper.DropTarget_PreviewDragOver),以及我得到了。
Now I found the function (DragDropHelper.DropTarget_PreviewDragOver) that I would want to do the testing of which item is being dragged over, and I'm getting that.
Dim pt As Point = e.GetPosition(DirectCast(Me.targetItemsControl, UIElement))
' Perform the hit test against a given portion of the visual object tree.
Dim result As HitTestResult = VisualTreeHelper.HitTest(Me.targetItemsControl, pt)
现在从在那里我可以得到这个视觉命中的依赖性属性
Now from there I can get the DependencyProperty of this visual hit
Dim lvi As ListViewItem = TryCast(GetDependencyObjectFromVisualTree(TryCast(result.VisualHit, DependencyObject), GetType(ListViewItem)), ListViewItem)
哪个是ListViewItem。现在在DropTarget_PreviewDragOver的函数中,我有DraggedItem,它的类型是Picture in Bea的例子,但是可以根据您已经绑定到ListView的ObservableCollection进行更改。现在,我想根据鼠标在控件上的位置向上或向下拖动ListView。我尝试使用以下未完成的非工作代码
Which is of a ListViewItem. Now in the function DropTarget_PreviewDragOver I have the "DraggedItem" which is of type Picture in Bea's example, but that can change depending on the ObservableCollection you have bound to the ListView. Now, I want to drag the ListView up or down depending on where the mouse is on the control. I've attempted with the below un-finished non-working code
If lvi IsNot Nothing Then
If pt.Y <= 25 Then
Dim lv As ListView = TryCast(targetItemsControl, ListView)
If lv IsNot Nothing Then
Dim index As Integer = lv.Items.IndexOf(lvi)
If index > 1 Then
lv.ScrollIntoView(lv.Items(index - 1))
End If
End If
Else
If pt.Y >= Me.targetItemsControl.ActualHeight - 25 Then
Debug.Print("Scroll Down")
End If
End If
End If
有人可以指向正确的方向,让这个ItemsControl或ListView在拖动项目时滚动?
Can someone point me in the right direction to get this ItemsControl or ListView to scroll when dragging over the items??
谢谢!
推荐答案
我还在搞砸这个完全相同的问题。我使用稍微修改版本的Bea's Drag and Drop发现这里,它是VB而不是C#。当我使用ScrollIntoView如上所述,我可以向下滚动但不能。所以我搞砸了,并提出了这个DropTarget_PreviewDragOver:
I'm still messing around with this exact same issue too. I'm using a slightly modified version of Bea's Drag and Drop found here, which is in VB instead of C#. When I used ScrollIntoView as described above, I could scroll down but not up. So I messed around and came up with this as my DropTarget_PreviewDragOver:
Private Sub DropTarget_PreviewDragOver(ByVal sender As Object, ByVal e As DragEventArgs)
Dim draggedItem As Object = e.Data.GetData(Me.m_format.Name)
Me.DecideDropTarget(e)
If (Not draggedItem Is Nothing) Then
If (TypeOf m_targetItemsControl Is ListBox) Then
Dim lb As ListBox = CType(m_targetItemsControl, ListBox)
Dim temp As Integer = m_insertionIndex
Dim scroll As ScrollViewer = Utilities.GetScrollViewer(lb)
If scroll.VerticalOffset = temp Then
temp -= 1
End If
If temp >= 0 And temp <= (lb.Items.Count - 1) Then
lb.ScrollIntoView(lb.Items(temp))
End If
End If
Me.ShowDraggedAdorner(e.GetPosition(Me.m_topWindow))
Me.UpdateInsertionAdornerPosition()
End If
e.Handled = True
End Sub
我不得不包含这个效用函数,取自这里
and I had to include this utility function, taken from here
Public Shared Function GetScrollViewer(ByVal listBox As ListBox)
Dim scroll_border As Decorator = CType(VisualTreeHelper.GetChild(listBox, 0), Decorator)
If (TypeOf scroll_border Is Decorator) Then
Dim scroll As ScrollViewer = CType(scroll_border.Child, ScrollViewer)
If (TypeOf scroll Is ScrollViewer) Then
Return scroll
Else
Return Nothing
End If
Else
Return Nothing
End If
End Function
这是非常好的,所有。然后用adorner移动上面提到的这个awuberk,并且为了让别人以后这个简单的精神,我向DragDropAdorner类添加了一个变量:
which is great and all. Then running out what theuberk mentioned above with the adorner moving, and in the spirit of making this easy for someone else later, I added a variable to the DragDropAdorner class:
Private m_mouseDelta As Point
将此添加到DragSource_PreviewMouseLeftButtonDown的最后一行:
Added this to the last line of DragSource_PreviewMouseLeftButtonDown:
Me.m_mouseDelta = e.GetPosition(m_sourceItemContainer)
并将ShowDraggedAdorner转换为:
And turned ShowDraggedAdorner into:
Private Sub ShowDraggedAdorner(ByVal currentPosition As Point)
If (Me.m_draggedAdorner Is Nothing) Then
Dim adornerLayer As AdornerLayer = adornerLayer.GetAdornerLayer(Me.m_topWindow.Content)
Me.m_draggedAdorner = New DraggedAdorner(Me.m_draggedData, DragDropBehavior.GetDragTemplate(Me.m_sourceItemsControl), m_topWindow.Content, adornerLayer)
End If
Me.m_draggedAdorner.SetPosition((currentPosition.X - m_mouseDelta.X), (currentPosition.Y - m_mouseDelta.Y))
End Sub
这篇关于WPF ListView数据绑定拖放自动滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!