禁用ListBox上的“拖动选择”

时间:2011-11-09 15:07:56

标签: c# winforms listbox

Winforms'ListBox似乎有一种奇怪的行为。当我将SelectionMode设置为1时,我希望我可以单击某个项目,然后它就会被选中。这是正确的,但是如果我单击一个项目,在列表中上下拖动,选择就会改变。

现在,除了我需要在某些控件之间执行拖放操作之外,这不是什么大不了的事。因此,当他们选择一个项目并将其向下拖动到列表中时,新选择的项目实际上是它注册为拖动的项目,并且错误的项目将被发送。

所以,然后我通过在mousedown上保存对所选项目的引用来进一步包扎它,但它最终会成为糟糕的用户体验。我的用户将项目拖动到另一个列表框,这确实有效,但原始列表框不再选择“正确”项目,并且他们对第二个控件上实际丢弃了哪个项目感到困惑。

那么,有没有办法改变这种行为?我希望在MouseDown中选择一个项目,忽略MouseUp部分内容。简单地使用该事件似乎不够,我宁愿不必重写ListBox(我们必须为正在创建的任何新类编写文档)。

1 个答案:

答案 0 :(得分:1)

我想如果你打电话给DoDragDrop,这种行为就会消失。在拖放模式下,Windows不会发送MouseOver条消息。

propper drag& drop的示例:

    private void listBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) 
    {
        // Get the index of the item the mouse is below.
        indexOfItemUnderMouseToDrag = listBox.IndexFromPoint(e.X, e.Y);

        if (indexOfItemUnderMouseToDrag != ListBox.NoMatches) {

            // Remember the point where the mouse down occurred. The DragSize indicates
            // the size that the mouse can move before a drag event should be started.                
            Size dragSize = SystemInformation.DragSize;

            // Create a rectangle using the DragSize, with the mouse position being
            // at the center of the rectangle.
            dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width /2),
                                                           e.Y - (dragSize.Height /2)), dragSize);
        } else
            // Reset the rectangle if the mouse is not over an item in the ListBox.
            dragBoxFromMouseDown = Rectangle.Empty;

    }

    private void listBox_MouseUp(object sender, System.Windows.Forms.MouseEventArgs e) {
        // Reset the drag rectangle when the mouse button is raised.
        dragBoxFromMouseDown = Rectangle.Empty;
    }

    private void listBox_MouseMove(object sender, System.Windows.Forms.MouseEventArgs e) 
    {
        if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {

            // If the mouse moves outside the rectangle, start the drag.
            if (dragBoxFromMouseDown != Rectangle.Empty && 
                !dragBoxFromMouseDown.Contains(e.X, e.Y)) 
            {
                    DragDropEffects dropEffect = listBox.DoDragDrop(listBox.Items[indexOfItemUnderMouseToDrag], DragDropEffects.All | DragDropEffects.Link);

                    // If the drag operation was a move then remove the item.
                    if (dropEffect == DragDropEffects.Move) {                        
                        listBox.Items.RemoveAt(indexOfItemUnderMouseToDrag);

                        // Selects the previous item in the list as long as the list has an item.
                        if (indexOfItemUnderMouseToDrag > 0)
                            listBox.SelectedIndex = indexOfItemUnderMouseToDrag -1;

                        else if (ListDragSource.Items.Count > 0)
                            // Selects the first item.
                            listBox.SelectedIndex =0;
                    }
                }
            }
        }
    }

...... SelectedIndexChanged仍有效!