滚动时防止拖放
本文关键字:拖放 滚动 | 更新日期: 2023-09-27 18:35:42
我正在做一个 Wpf 项目,但现在我遇到了一个ListView
问题。
事实证明,我已经在ListView上实现了Drag&Drop
功能,该功能运行良好。当我尝试向下或向上滚动时,问题就来了。通过这样做,Drag&Drop
功能被激活,阻止我继续滚动。
我找到了这个解决方案,它表明我们需要将控件附加到ScrollChanged
事件。
<ListView ScrollViewer.ScrollChanged="listView1_ScrollChanged"...
但我真的不知道在那个处理程序中该怎么做。如何从该事件中禁用拖放?我怎样才能再次启用它?或者,有没有更好的方法来解决这个问题?
这是我的Drag&Drop
代码:
private void listView1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Store the mouse position
startPoint = e.GetPosition(null);
}
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
// Get the dragged ListViewItem
ListView listView = sender as ListView;
// Get items to drag
var a = listView.SelectedItems;
// Initialize the drag & drop operation
DataObject dragData = new DataObject("myFormat", a);
DragDrop.DoDragDrop(listView, dragData, DragDropEffects.Move);
}
}
提前谢谢。
如果您不在 MouseDown 事件中,则可以阻止 MouseMove 事件:
bool stopDrag = true;
private void listView1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Store the mouse position
startPoint = e.GetPosition(null);
stopDrag = false;
}
private void listView1_MouseMove(object sender, MouseEventArgs e)
{
if(stopDrag)
return;
// Get the current mouse position
Point mousePos = e.GetPosition(null);
Vector diff = startPoint - mousePos;
if (e.LeftButton == MouseButtonState.Pressed &&
(Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
{
// Get the dragged ListViewItem
ListView listView = sender as ListView;
// Get items to drag
var a = listView.SelectedItems;
// Initialize the drag & drop operation
DataObject dragData = new DataObject("myFormat", a);
DragDrop.DoDragDrop(listView, dragData, DragDropEffects.Move);
}
}
private void listView1_MouseUp(...)
{
stopDrag = true;
}
这应该有效,我在浏览器中写了它,所以如果我做错了什么,请原谅我,对于格式,我希望你明白了。
我使用一个简单的方法来确认拖动操作是否得到确认,使用为此目的而SystemParameters.MinimumHorizontalDragDistance
和SystemParameters.MinimumVerticalDragDistance
:
private bool IsDragConfirmed(Point point)
{
bool horizontalMovement = Math.Abs(point.X - dragStartPosition.X) >
SystemParameters.MinimumHorizontalDragDistance;
bool verticalMovement = Math.Abs(point.Y - dragStartPosition.Y) >
SystemParameters.MinimumVerticalDragDistance;
return (horizontalMovement | verticalMovement);
}
它在PreviewMouseMove
事件中被称为...下面是一个简化的示例:
private void DragSourcePreviewMouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown && IsDragConfirmed(e.GetPosition(sender as ListBox)))
{
// Start your drag operation here
}
}
我遇到了与以下答案相同的问题和相同的来源。好吧,我决定防止拖动,如果鼠标位置不在列表视图项目上(矩形 0, 0, lv.width - scroll.width, lv.height - scroll.height)所以我有一个"allowdrag"标志,如果在 PreviewMouseLeftButtonDown 经过时鼠标指针位于必要的矩形上,则该标志变为 True。
VB.NET
Private allowdrag As Boolean
Private Sub lv_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs) Handles lvAttributesDefault.PreviewMouseLeftButtonDown
Dim listView As ListView = TryCast(sender, ListView)
allowdrag = e.GetPosition(sender).X < listView.ActualWidth - SystemParameters.VerticalScrollBarWidth And e.GetPosition(sender).Y < listView.ActualHeight - SystemParameters.HorizontalScrollBarHeight
End Sub
Private Sub lv_MouseMove(sender As Object, e As MouseEventArgs) Handles lvAttributesDefault.MouseMove
Dim listView As ListView = TryCast(sender, ListView)
If e.LeftButton = MouseButtonState.Pressed And listView.SelectedItem IsNot Nothing And allowdrag Then
Dim obj As clsAttribute = CType(listView.SelectedItem, clsAttribute)
Dim dragData As New DataObject("clsAttribute", obj)
DragDrop.DoDragDrop(listView, dragData, DragDropEffects.Copy)
End If
End Sub
C# (telerik code converter)
private bool allowdrag;
private void lv_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ListView listView = sender as ListView;
allowdrag = e.GetPosition(sender).X < listView.ActualWidth - SystemParameters.VerticalScrollBarWidth & e.GetPosition(sender).Y < listView.ActualHeight - SystemParameters.HorizontalScrollBarHeight;
}
private void lv_MouseMove(object sender, MouseEventArgs e)
{
ListView listView = sender as ListView;
if (e.LeftButton == MouseButtonState.Pressed & listView.SelectedItem != null & allowdrag) {
clsAttribute obj = (clsAttribute)listView.SelectedItem;
DataObject dragData = new DataObject("clsAttribute", obj);
DragDrop.DoDragDrop(listView, dragData, DragDropEffects.Copy);
}
}
clsAttribute 是我的自定义类。这listview 绑定到 ObservableCollection(of clsAttribute)