2011-01-28 2 views
1

Я пытаюсь реализовать щелчок и перетаскивать выделение, как в проводнике Windows (синий прямоугольник выбора, который появляется, когда вы держите кнопку мыши и перемещаете мышь).MouseEnter/MouseLeave и мышь левая кнопка вниз

Итак, у меня есть ListView со стилизованным шаблоном ListViewItem. Я добавил событие MouseEnter и MouseLeave в свой ListViewItem (с помощью EventSetter), Он отлично работает, если не нажать левую кнопку мыши. В этом случае события не срабатывают, что плохо для того, чего я пытаюсь достичь.

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

На данный момент я пробовал с VisualTreeHelper.HitTest(), но я знаю только, когда пересекаю ListViewItem, и мне нужно знать, когда я его оставлю.

Спасибо.

ответ

0

Даже если были запущены ваши события MouseEnter и Leave, которые не предоставили бы хороший метод для выбора, потому что оба события не имеют значения в конце: не имеет значения, когда ваша мышь когда-либо касалась этой папки или файла, все, что имеет значение, это если он находится в прямоугольнике в момент времени, когда вы отпускаете кнопку. Это означает, что Mouse Up & Down должно быть достаточно. В зависимости от вашего списка вы даже можете определить, какие элементы следует выбирать, просто просматривая два элемента, на которых произошли эти события (например, если это просто одномерный список, а не двумерная сетка).

Если у вас есть сетка, вам понадобится более сложная механика, например, отслеживание зоны покрытия и проверка того, какие предметы находятся внутри или на краю.

+0

Проблема с этим методом заключается в том, что мои элементы выбираются только тогда, когда пользователь отпускает кнопку мыши, в моем случае я хочу быть ближе к поведению проводника Windows, что означает выбор/отмена выбора элементов, когда мышь/«синий прямоугольник выбора» "находится над предметом. Если я сделаю выбор после того, как он выполнит задания, но внешний вид и опыт UX не будут такими же хорошими, как ожидалось, и я хочу как можно больше поддерживать согласованность с поведением Windows по умолчанию. – StrAbZ

+0

Затем вы можете обрабатывать 'MouseMove' в' ListView', проверить, не нажата ли соответствующая кнопка мыши, а также проверить, возвращает ли 'Mouse.DirectlyOver'' ListViewItem'. Если это возможно, вы можете выбрать его и/или снять выделение с элемента, над которым была указана последняя. Сложно, но это всего лишь небольшое логическое взаимодействие. –

+0

У меня может быть указатель мыши IsDirectlyOver, проверенный по каждому элементу, но это потребует удаления MouseCapture, чего я не хочу. Если я чего-то не упущу. – StrAbZ

1

При нажатии кнопки UIElement.CaptureMouse необходимо снять мышь UIElement.ReleaseMouseCapture во время события MouseUp. Вам не нужно беспокоиться о каких-либо других событиях, потому что все входные данные мыши поступают на ваш UIElement во время захвата.

Эта форма выбора называется «выбор лассо», и большинство виджетов в приложениях Windows поддерживают ее. Фактически, сам ListView уже делает.

+0

Хорошо, но я до сих пор ничего не понимаю, так как я запечатлел мышь (и отпустил ее) в своем представлении списка, как я могу получить информацию о том, какой элемент перемещается? У меня нет элемента события, и я не знаю, как проверить, находится ли мышь в границах ListViewItem (кроме того, что я уже делаю с VisualTreeHelper.HitTest()) – StrAbZ

+0

@StrAbZ: Googled it для вас: http://manfredlange.blogspot.com/2009/04/listviewgetitemat-in-wpf-application.html – Tergiver

+0

Спасибо, это похоже на часть работы. Он работает для указателя мыши, мне все равно нужно выяснить, как определить, какие элементы находятся в моей зоне выбора, а не только указатель мыши. – StrAbZ

0

Итак, я нашел другое решение для обработки этого поведения.

Я начал с этим StackOverflow ответ Click and drag selection box in WPF

В MouseMove, после изменения размера selectionBox, я выбираю те элементы, которые находятся в регионе selectionBox.

я сделать это таким образом:

//Select all visible items in select region. 
Rect selectRect = new Rect(Canvas.GetLeft(selectionBox), Canvas.GetTop(selectionBox), 
       (Canvas.GetLeft(selectionBox) + selectionBox.Width), (Canvas.GetTop(selectionBox) + selectionBox.Height)); 

RectangleGeometry rr = new RectangleGeometry(selectRect); 
foreach (CustomElement elt in mainList.Items) 
{ 
    ListViewItem item = mainList.ItemContainerGenerator.ContainerFromItem(elt) as ListViewItem; 
    Rect r = LayoutInformation.GetLayoutSlot(item); 
    if (r.IntersectsWith(selectRect)) 
     item.IsSelected = true; 
    else 
     item.IsSelected = false; 
} 

Я обнаружил, что LayoutInformation может дает Rect, которые представляют свой объект, так что я могу проверить, если она пересекается с selectionBox Rect.

Смежные вопросы