除了一个小小的烦人问题,我几乎解决了这个问题...
由于 ListBox 的选择是在鼠标按下时发生的,如果你在选择要拖动的最后一项时用鼠标按下开始拖动,那么它就能正常工作,但如果你先选择所有要拖动的项,然后再点击选择开始拖动,你所点击的那个被取消选中并被留在原地。
有什么好的方法可以解决这个问题吗?
<DockPanel LastChildFill="True">
<ListBox ItemsSource="{Binding SourceItems}"
SelectionMode="Multiple"
PreviewMouseLeftButtonDown="HandleLeftButtonDown"
PreviewMouseLeftButtonUp="HandleLeftButtonUp"
PreviewMouseMove="HandleMouseMove"
MultiSelectListboxDragDrop:ListBoxExtension.SelectedItemsSource="{Binding SelectedItems}"/>
<ListBox ItemsSource="{Binding DestinationItems}"
AllowDrop="True"
Drop="DropOnToDestination"/>
<DockPanel>
...
public partial class Window1
{
private bool clickedOnSourceItem;
public Window1()
{
InitializeComponent();
DataContext = new WindowViewModel();
}
private void DropOnToDestination(object sender, DragEventArgs e)
{
var viewModel = (WindowViewModel)
e.Data.GetData(typeof(WindowViewModel));
viewModel.CopySelectedItems();
}
private void HandleLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var sourceElement = (FrameworkElement)sender;
var hitItem = sourceElement.InputHitTest(e.GetPosition(sourceElement))
as FrameworkElement;
if(hitItem != null)
{
clickedOnSourceItem = true;
}
}
private void HandleLeftButtonUp(object sender, MouseButtonEventArgs e)
{
clickedOnSourceItem = false;
}
private void HandleMouseMove(object sender, MouseEventArgs e)
{
if(clickedOnSourceItem)
{
var sourceItems = (FrameworkElement)sender;
var viewModel = (WindowViewModel)DataContext;
DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);
clickedOnSourceItem = false;
}
}
}
try...finally
块?会出现什么问题,它可以安全地忽略吗? - mikefinally
语句块确保在事件处理结束时正确重置_deferSelection
。那是五年前的事了,所以不知道实际上会有什么异常导致那里出错,但我猜测任何其他处理该事件的程序都可能搞砸。 - David SchmittListView
也适用。 - Oliver Giesen