WPF从具有SelectionMode = Extended的ListBox拖放

时间:2010-09-22 08:59:50

标签: wpf listbox drag-and-drop itemscontrol

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

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

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

3 个答案:

答案 0 :(得分:8)

这就是我所做的。在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 :(得分:2)

我能想到的最简单的解决方法是更改​​ListBoxItem以在MouseUp上选择而不是像这样选择并更改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逻辑。

答案 2 :(得分:0)

使用PreviewMouseLeftButtonDown为拖动操作添加所选项目。