Winforms'ListBox
似乎有一种奇怪的行为。当我将SelectionMode
设置为1时,我希望我可以单击某个项目,然后它就会被选中。这是正确的,但是如果我单击一个项目,在列表中上下拖动,选择就会改变。
现在,除了我需要在某些控件之间执行拖放操作之外,这不是什么大不了的事。因此,当他们选择一个项目并将其向下拖动到列表中时,新选择的项目实际上是它注册为拖动的项目,并且错误的项目将被发送。
所以,然后我通过在mousedown上保存对所选项目的引用来进一步包扎它,但它最终会成为糟糕的用户体验。我的用户将项目拖动到另一个列表框,这确实有效,但原始列表框不再选择“正确”项目,并且他们对第二个控件上实际丢弃了哪个项目感到困惑。
那么,有没有办法改变这种行为?我希望在MouseDown中选择一个项目,忽略MouseUp部分内容。简单地使用该事件似乎不够,我宁愿不必重写ListBox(我们必须为正在创建的任何新类编写文档)。
答案 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
仍有效!