禁用ListBox上的“拖动选择”

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

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

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

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

我想如果你调用DoDragDrop这种行为就会消失。 在拖放模式下,Windows不会调度MouseOver消息。

propper拖放示例:

  private void listBox_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e) { // Get the index of the item the mouse is below. indexOfItemUnderMouseToDrag = listBox.IndexFromPoint(eX, eY); 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(eX - (dragSize.Width /2), eY - (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(eX, eY)) { 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仍然有效!