禁用“拖动选择".在列表框上 [英] Disabling "Drag Selection" on ListBox

查看:119
本文介绍了禁用“拖动选择".在列表框上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Winforms' ListBox appears to have a strange behavior. When I set the SelectionMode to one, I expect that I can click an item, and it becomes selected. This holds true, but if I click an item, drag up and down the list, the selection changes.

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

Now, that wouldn't be too much of a big deal except that I need to perform drag and drop between some controls. So, when they select an item, and drag it down the list, a newly-selected item is actually the one it registers as dragging, and the wrong item gets sent over.

因此,我随后通过在鼠标按下时保存对选定项目的引用来进一步包扎它,但最终会带来糟糕的用户体验.我的用户将一个项目拖到另一个列表框上,该列表确实起作用,但是原来的列表框不再选择正确"的项目,并且他们对于实际上哪个项目被放置在第二个控件上感到困惑.

So, I then further bandage it by saving a reference to the selected item on mousedown, but it winds up as a bad user experience. My users drag an item to the other listbox, which does work, but the original listbox doesn't have the "correct" item selected anymore, and they become confused as to which item was actually dropped on the second control.

那么,有什么办法可以改变这种行为?我希望在MouseDown处选择一个项目,而忽略MouseUp部分.仅仅消耗事件似乎还不够,我宁愿不必重写ListBox(我们必须为正在创建的任何新类编写文档).

So, is there any way to change this sort of behavior? I want an item to be selected at MouseDown, ignoring the MouseUp part of things. Simply consuming the event doesn't seem to be enough, and I'd rather not have to override ListBox (we have to write documents for any new classes being created).

推荐答案

我猜如果您调用DoDragDrop,此行为将消失.在拖放模式下,Windows不会调度MouseOver消息.

I guess if you call DoDragDrop this behavior would disappear. Windows doesn't dispatch MouseOver messages while in drag&drop mode.

正确拖放的示例:

    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仍然有效!

这篇关于禁用“拖动选择".在列表框上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆