Почему реализация поведения WPF DragDrop останавливает выбор ListBoxItems с первого клика? - PullRequest
0 голосов
/ 07 декабря 2011

В течение некоторого времени я довольно успешно реализовывал базовые функции перетаскивания с использованием WPF и C #. У меня всегда была одна проблема после ее реализации, хотя ... по какой-то причине, функция перетаскивания мешает выбору ListBoxItem s (при первом нажатии).

Если я нажимаю на ListBoxItem, но не перетаскиваю его, он не выбирается, и значок перетаскивания появляется на мгновение. При следующем щелчке я могу выбрать любой из ListBoxItem s, и значок перетаскивания не появляется. Затем этот цикл повторяется ... первый щелчок не будет выбран, второй будет.

Ниже приведена типичная реализация моего кода перетаскивания, взятого из книги «Учебный комплект» Micorsoft MCTS 70-511.

private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    object data = (ListBoxItem)(FrameworkElement)sender;
    if (data != null) DragDrop.DoDragDrop(ListBox, data, DragDropEffects.Copy);
    e.Handled = false;
}

private void ListBox_DragEnter(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(ListBoxItem))) e.Effects = DragDropEffects.Copy;
}

private void ListBox_Drop(object sender, DragEventArgs e)
{
    object data = e.Data.GetData(typeof(ListBoxItem));
    if (data != null) DoSomethingWith((DataType)((ListBoxItem)data).DataContext);
}

Перетаскивание работает отлично, но выбор элемента не ... Я предположил, что, добавив e.Handled = false в обработчик ListBox_PreviewMouseLeftButtonDown, механизм выбора ListBoxItem может обработать событие click, но он никогда не будет достигает этого далеко.

Я также пытался обработать инициацию перетаскивания в обработчике MouseLeftButtonDown вместо обработчика PreviewMouseLeftButtonDown, но механизм выбора ListBoxItem обрабатывает событие click, и он никогда не достиг этого обработчика перетаскивания.

Должен быть способ инициировать операцию перетаскивания и все еще иметь выбранный ListBoxItem, но мне все еще не удалось его найти ... есть какие-нибудь подсказки?

ОБНОВЛЕНИЕ >>>

Благодаря статье в MSDN, которую @icebat предоставил ссылку, мне удалось добиться идеальной работы функции перетаскивания. Теперь это выглядит следующим образом:

private void SourceListBox_MouseMove(object sender, MouseButtonEventArgs e)
{
    if (e.LeftButton == MouseButtonState.Pressed)
    {
        object data = ((ListBox)(FrameworkElement)sender).SelectedItem;
        if (data != null) 
            DragDrop.DoDragDrop(SourceListBox, data, DragDropEffects.Copy);
    }
}

private void TargetListBox_DragOver(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent(typeof(DragObject))) e.Effects = DragDropEffects.Copy;
}

private void TargetListBox_Drop(object sender, DragEventArgs e)
{
    object data = e.Data.GetData(typeof(DragObject));
    if (data != null) DoSomethingWith((DragObject)data);
}

1 Ответ

2 голосов
/ 07 декабря 2011

Просто используйте событие MouseMove вместо MouseDown для перетаскивания.Вы можете найти больше информации и некоторый код в статье Drag and Drop на MSDN.

...