【问题标题】:WPF drag and drop from a ListBox that has SelectionMode=ExtendedWPF 从具有 SelectionMode=Extended 的 ListBox 拖放
【发布时间】:2010-09-22 08:59:49
【问题描述】:

我有一个 ListBox 并希望扩展选择模式。我还想实现拖放功能。现在的问题是,如果鼠标单击选定的项目,它将立即被选择为单选而不是等待鼠标向上事件来执行此操作。

由于这种行为,开始拖动多个项目对于用户来说几乎是不可能的,因为他总是单击选择开始拖动,选择更改为鼠标下方的项目并开始使用该项目进行拖动操作。

这个问题是否有很好的解决方法,甚至是否存在官方解决方案?

【问题讨论】:

  • 您稍后再次接受不同的答案。因此,如果您更喜欢另一个答案,请接受。
  • 我推荐使用下面的链接。它工作得很好。 stackoverflow.com/a/23151248

标签: wpf listbox drag-and-drop itemscontrol


【解决方案1】:

这就是我所做的。在您的 DragDrop 代码中,订阅 PreviewMouseLeftButtonDown。如果您已经点击的项目被选中,则将 e.Handled 设置为 true。

在下面的示例中,我将列表框项目的一部分标识为拖动夹点(带有凸起),以便我可以区分项目和拖动表面。我只需要获取列表框项数据模板和拖放行为就可以就拖动夹点元素的名称达成一致。

我正在进行的工作中的 PreviewMouseLeftButtonDown:

private void ItemsControl_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    dragStartPoint = e.GetPosition(null);

    ItemsControl itemsControl = this.AssociatedObject as ItemsControl;
    if (itemsControl != null)
    {
        this.sourceItemContainer = itemsControl.ContainerFromElement((Visual)e.OriginalSource) as FrameworkElement;
    }

    // If this is an multiple or extended selection list box, and on a drag grip, then ensure the item being hit is selected
    // This prevents the ItemsControl from using this MouseDown to change selection, except over a selected item's drag grip.            
    if ((this.IsMultipleSelectionListBox() == true) && (this.IsOriginalSourceDragGrip(e) != false) && (this.IsSourceListBoxItemSelected() == true))
    {
        e.Handled = true;
    }
}

【讨论】:

  • +1 是的,最后,我以类似的方式解决了它。感谢您的回答。但是我已经接受了 MrDosu 的回答。但我会向其他想要解决同样问题的人推荐你的方法。
【解决方案2】:

我能想到的最简单的解决方法是将 ListBoxItem 更改为在 MouseUp 而不是 Down 上选择,然后更改 ContainerGenerator 以提供您的自定义 ListBoxItems:

public class CustomListBoxItem : ListBoxItem  
{  
    protected override void OnMouseLeftButtonDown( MouseButtonEventArgs e )  
    {  
        //do nothing
    }  

    protected override void OnMouseLeftButtonUp( MouseButtonEventArgs e )  
    {  
        base.OnMouseLeftButtonDown( e );  
    }  
}  

如果您想防止在按住鼠标按钮的同时在列表中移动时选择不同的项目,您可能需要一些 MouseLeave/LeftButtonDown 逻辑。

【讨论】:

  • +1 不错的解决方案。但是我有点担心,因为我不知道从调用方法中调用另一个事件是否会导致 FCL 的未来版本出现问题。
  • 当 EventArgs 预计会有所不同(如按钮状态)时,可能需要进行一些精心设计,但看到事件的处理程序只是被调用,我想不出一个突破性的变化场景。跨度>
  • 不幸的是,这太简单了,因为在某些情况下,鼠标按下时会有选择活动。正确的行为是在鼠标按下时选择(或扩展选择)未选中的项目(如果它已经被选中则不会发生变化),而取消选择已选中的项目仅在鼠标向上时发生,并且只有在没有明显的光标时发生了运动。
【解决方案3】:

使用PreviewMouseLeftButtonDown为拖拽操作添加选中项。

【讨论】:

    猜你喜欢
    • 2010-12-05
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2014-03-19
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多