Итак ... став счастливым обладателем значка с завитками, я вернулся к этому, чтобы попытаться найти способ обойти это. ; -)
Я не уверен, что мне нравится решение, поэтому я все еще очень открыт для любых более подходящих подходов.
По сути, в итоге я запомнил, на что последний раз нажимали ListBoxItem, и затем убедитесь, что он добавляется к выбранным элементам перед перетаскиванием. Это также означало анализ того, насколько далеко мышь перемещается перед началом перетаскивания, поскольку нажатие на выбранный элемент для отмены выбора может иногда привести к его повторному выделению, если отскок мыши запустил небольшую операцию перетаскивания.
Наконец, я добавил горячее отслеживание к элементам списка, поэтому, если вы щелкнете мышью по выбранному элементу, он не будет выбран, но вы все равно получите некоторую обратную связь, чтобы указать, что он будет включен в операцию перетаскивания.
private void HandleLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var source = (FrameworkElement)sender;
var hitItem = source.InputHitTest(e.GetPosition(source)) as FrameworkElement;
hitListBoxItem = hitItem.FindVisualParent<ListBoxItem>();
origPos = e.GetPosition(null);
}
private void HandleLeftButtonUp(object sender, MouseButtonEventArgs e)
{
hitListBoxItem = null;
}
private void HandleMouseMove(object sender, MouseEventArgs e)
{
if (ShouldStartDrag(e))
{
hitListBoxItem.IsSelected = true;
var sourceItems = (FrameworkElement)sender;
var viewModel = (WindowViewModel)DataContext;
DragDrop.DoDragDrop(sourceItems, viewModel, DragDropEffects.Move);
hitListBoxItem = null;
}
}
private bool ShouldStartDrag(MouseEventArgs e)
{
if (hitListBoxItem == null)
return false;
var curPos = e.GetPosition(null);
return
Math.Abs(curPos.Y-origPos.Y) > SystemParameters.MinimumVerticalDragDistance ||
Math.Abs(curPos.X-origPos.X) > SystemParameters.MinimumHorizontalDragDistance;
}
Изменения XAML включают горячее отслеживание ...
<Style TargetType="ListBoxItem">
<Setter Property="Margin" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border Background="{TemplateBinding Background}" />
<Border Background="#BEFFFFFF" Margin="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition /><RowDefinition />
</Grid.RowDefinitions>
<Border Margin="1" Grid.Row="0" Background="#57FFFFFF" />
</Grid>
</Border>
<ContentPresenter Margin="8,5" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="PowderBlue" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#5FB0E0E6" />
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>