【问题标题】:Prevent Drag & Drop When Scrolling滚动时防止拖放
【发布时间】:2013-10-15 21:09:59
【问题描述】:

我正在处理一个 Wpf 项目,但现在我遇到了 ListView 问题。

事实证明,我在 ListView 上实现了 Drag&Drop 功能,效果很好。当我尝试向下或向上滚动时,问题就来了。通过这样做,Drag&Drop 功能被激活,阻止我继续滚动。

我找到了this solution,这表明我们需要将控件附加到ScrollChanged 事件。

<ListView ScrollViewer.ScrollChanged="listView1_ScrollChanged"...

但我真的不知道在那个处理程序中该做什么。 如何禁用该事件的拖放功能?我怎样才能再次启用它?或者,有没有更好的方法来解决这个问题?

这是我的Drag&amp;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);
        } 
    }

提前致谢。

【问题讨论】:

  • 也许你能告诉我们你是如何实现拖放功能的......
  • @Georgi-it 添加代码

标签: c# wpf listview drag-and-drop scroll


【解决方案1】:

如果您不在 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;
}

这应该可以,我是在浏览器中写的,如果我做错了什么,请原谅,对于格式,我希望你明白。

【讨论】:

  • 你好,我刚试过,但没有用,它一直以同样的方式运行:(
  • 理论上它应该可以工作,也许如果你调试它并给我一些额外的信息..
  • 我这样做了,这里的问题是当我按下鼠标左键时stopDrag变成false,所以,当它得到listView1_MouseMove方法时,条件if(stopDrag) return不满足。我可以反转条件,但是通过这样做,Drag&Drop 功能永远不会启动,因为我的 Drag&Drop 功能在 PreviewMouseLeftButtonDown 事件中开始获取鼠标的位置
【解决方案2】:

我使用了一个简单的方法来确认拖动操作是否被确认,使用为此目的制作的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
    }
}

【讨论】:

    【解决方案3】:

    我遇到了与以下答案相同的问题和相同的来源。 好吧,如果鼠标位置不在列表视图项目上方,我决定防止拖动(矩形 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 代码转换器)

    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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      • 1970-01-01
      • 2014-12-16
      • 1970-01-01
      • 2022-07-15
      相关资源
      最近更新 更多