Как цель отбрасывания обнаруживает отмененное перетаскивание в WPF? - PullRequest
1 голос
/ 28 октября 2011

Я пытаюсь написать некоторый общий код для обработки отбрасываний в целевых объектах отбрасывания WPF. AllowDrop установлен в true, и я подключил DragEnter, DragOver, DragLeave, & Drop к целевому UIElement. Использование всплывающих событий позволяет вложить цели отбрасывания.

Примечание. У меня нет доступа к источнику перетаскивания - это перетаскивание между приложениями.

Если у меня есть некоторая очистка пользовательского интерфейса для выполнения в конце потенциального отбрасывания, и пользователь нажимает клавишу Esc, чтобы отменить отбрасывание, кажется, что цель отбрасывания никогда не получает определенного события, которое я могу отличить от всех остальных. Отбросить легко, но что означает отмену?

У меня проблема в следующем:

  • DragLeave - это пузырчатое перенаправленное событие.
  • e.OriginalSource всегда устанавливается для этого события (и соответствующего предварительного просмотра) через тестирование.
  • Цель - ItemsControl (Listbox - это то, с чем я сейчас тестирую).

Когда я перетаскиваю намеченную цель перетаскивания, я получаю множество событий DragLeave от дочерних визуальных объектов в пределах цели. Я никогда не получаю ничего от самой цели. Сетки, прямоугольники, границы, текстовые блоки, они все радостно посылают мне DragLeave, но ни один из фактических ItemsControl, к которым я подключен. Я подумал, что это может быть проблема тестирования на попадание, но я установил цвет фона ItemsControl, и это не имеет значения.

Что мне не хватает? Как я должен определить, что операция удаления определенно завершена?

(Фактическая проблема, которую я пытаюсь решить, заключается в том, что я реализую некоторые пользовательские функции перетаскивания в TreeView, который расширяет папки при наведении на них курсора и отменяет таймеры и отменяет раскрытие по окончании удаления и т. Д. чтобы прийти, но я не могу даже заставить события срабатывать разумно для ListBox).

Ответы [ 2 ]

0 голосов
/ 28 декабря 2012

проверка для e.Source , а не e.OriginalSource, если вы установили DropTarget = "True" на ItemsControl и у вас есть событие DropOver, прикрепленное к ItemsControl, аргумент события e.Source должен быть ItemsControl.

0 голосов
/ 28 октября 2011

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

Каркас будет информировать о событии DragEnter, только если элемент управления помечен как AllowDrop =.правда.Поэтому убедитесь, что вы сделали это.Звучит так, как будто у вас есть, но я просто хочу быть уверен.

Я не уверен, зачем вам нужно событие DragLeave, но если это захват выбранных данных, самый простой способ получить данные - это не подключиться кDragLeave, но подключиться к PreviewMouseMove.Затем вы можете определить, нажата ли мышь и как далеко от нее пройти, прежде чем принимать DoDragDrop.

В этом случае у вас также есть возможность добавлять и анализировать данные перетаскивания.Когда начинается перетаскивание, вы можете создать новый объект DataObject и отправить его с помощью вызова DoDragDrop:

  private static void listBox_PreviewMouseMove(object sender, MouseEventArgs e)
  {
     // Get the current mouse position
     var mousePos = e.GetPosition(null);
     var diff = startPoint - mousePos;

     if (canScroll && e.LeftButton == MouseButtonState.Pressed &&
         (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
          Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
     {
        var dataObject = (from lbi in startList.Items.Cast<object>().Select((t, i) => (ListBoxItem)startList.ItemContainerGenerator.ContainerFromIndex(i)) where lbi != null && lbi.IsSelected select Convert.ToString(lbi.Content)).ToList();

        // Initialize the drag & drop operation
        var listBoxData = new ListBoxData(){ StartList = startList, Data = dataObject};
        var dragData = new DataObject("listBoxData", listBoxData);

        System.Windows.DragDrop.DoDragDrop(startList, dragData, DragDropEffects.Move);
     }
  }

Эти данные перетаскивания теперь доступны через объект DragEventArgs с помощью (если вы не переименовываете параметр события,это е):

e.Data.GetData("listBoxData")

Я предлагаю добавить некоторую уникальную информацию к данным события перетаскивания, чтобы дифференцировать событие на основе данных.Либо ваш элемент данных из списка выбора, либо новый класс, содержащий ваш элемент данных и другой индикатор, если это необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...