10
votes

WPF ListView Faites glisser Sélectionner plusieurs éléments

Je me demandais simplement si quelqu'un a une idée sur la façon de faire cela. Je veux laisser l'utilisateur sélectionner plusieurs éléments en cliquant sur la souris et en faisant glisser la souris (sans laisser le clic aller). Disons que l'utilisateur clique sur l'élément 1, puis glisse vers l'élément 10; L'article 1 à 10 devrait être sélectionné comme s'il cliquait sur l'élément 1, puis changez + cliqué sur l'élément 10.

laissez-moi savoir merci!


2 commentaires

Je l'ai résolu, je posterai la solution plus tard. Merci.


J'ai posté une nouvelle solution à cette question sur WPF Drag & Drop de la liste de liste avec sélectionMode multiple .


3 Réponses :


12
votes

OK Voici ma solution, j'ai créé une classe d'assistrage qui gère le prévisualiseurftmouseButTondown et la mouseleftbuttonup pour la listeView, et un petit style pour la listeVievemes qui, lorsque la souris est terminée, il indique la classe d'assistance, de sorte qu'il peut décider s'il sélectionne le article ou non (basé sur le bouton gauche de la souris enfoncé ou non). Quoi qu'il en soit, voici le projet complet:

xaml: xxx

c #: xxx

afin que vous puissiez le voir, Tout ce que vous avez à faire est d'ajouter le style de votre XAML et de définir le:

local: dragselectionhelper.isdragselectionnédeceenabled = "vrai"

propriété attachée à la liste de liste et ça Prenez soin de tout.

merci!


0 commentaires

2
votes

Notez également que avec SélectionMode = étendue Ceci est déjà possible, si l'utilisateur détient la touche shift avant le bouton de la souris vers le bas.


0 commentaires

5
votes

Basé sur la réponse de Carlo, j'ai modifié une partie de son code, vous pouvez maintenant utiliser CTRL pour continuer à sélectionner sans effacer la sélection de courant et utiliser Shift pour sélectionner des éléments tels que le mode "étendu".

using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;

namespace SteamFriendsManager.Utility
{
    public class DragSelectionHelper : DependencyObject
    {
        #region IsDragSelectionEnabledProperty

        public static bool GetIsDragSelectionEnabled(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsDragSelectionEnabledProperty);
        }

        public static void SetIsDragSelectionEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsDragSelectionEnabledProperty, value);
        }

        public static readonly DependencyProperty IsDragSelectionEnabledProperty =
            DependencyProperty.RegisterAttached("IsDragSelectingEnabled", typeof (bool), typeof (DragSelectionHelper),
                new UIPropertyMetadata(false, IsDragSelectingEnabledPropertyChanged));

        private static void IsDragSelectingEnabledPropertyChanged(DependencyObject o,
            DependencyPropertyChangedEventArgs e)
        {
            var listBox = o as ListBox;

            if (listBox == null)
                return;

            // if DragSelection is enabled
            if (GetIsDragSelectionEnabled(listBox))
            {
                // set the listbox's selection mode to multiple ( didn't work with extended )
                listBox.SelectionMode = SelectionMode.Multiple;

                // and subscribe to the required events to handle the drag selection and the attached properties
                listBox.PreviewMouseRightButtonDown += listBox_PreviewMouseRightButtonDown;

                listBox.PreviewMouseLeftButtonDown += listBox_PreviewMouseLeftButtonDown;
                listBox.PreviewMouseLeftButtonUp += listBox_PreviewMouseLeftButtonUp;

                listBox.PreviewKeyDown += listBox_PreviewKeyDown;
                listBox.PreviewKeyUp += listBox_PreviewKeyUp;
            }
            else // is selection is disabled
            {
                // set selection mode to the default
                listBox.SelectionMode = SelectionMode.Extended;

                // unsuscribe from the events
                listBox.PreviewMouseRightButtonDown -= listBox_PreviewMouseRightButtonDown;

                listBox.PreviewMouseLeftButtonDown -= listBox_PreviewMouseLeftButtonDown;
                listBox.PreviewMouseLeftButtonUp -= listBox_PreviewMouseLeftButtonUp;

                listBox.PreviewKeyDown -= listBox_PreviewKeyDown;
                listBox.PreviewKeyUp += listBox_PreviewKeyUp;
            }
        }

        private static void listBox_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            var listBox = sender as ListBox;
            if (listBox == null)
                return;

            if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
            {
                SetIsDragSelectionEnabled(listBox, false);
            }
        }

        private static void listBox_PreviewKeyUp(object sender, KeyEventArgs e)
        {
            var listBox = sender as ListBox;
            if (listBox == null)
                return;

            if (e.Key == Key.LeftShift || e.Key == Key.RightShift)
            {
                SetIsDragSelectionEnabled(listBox, true);
            }
        }

        private static void listBox_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            // to prevent the listbox from selecting / deselecting wells on right click
            e.Handled = true;
        }

        private static void listBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            SetIsDragClickStarted(sender as DependencyObject, true);
        }

        private static void listBox_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            SetIsDragClickStarted(sender as DependencyObject, false);
        }

        public static DependencyObject GetParent(DependencyObject obj)
        {
            if (obj == null)
                return null;

            var ce = obj as ContentElement;
            if (ce == null) return VisualTreeHelper.GetParent(obj);

            var parent = ContentOperations.GetParent(ce);
            if (parent != null)
                return parent;

            var fce = ce as FrameworkContentElement;
            return fce != null ? fce.Parent : null;
        }

        #endregion IsDragSelectionEnabledProperty

        #region IsDragSelectingProperty

        public static bool GetIsDragSelecting(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsDragSelectingProperty);
        }

        public static void SetIsDragSelecting(DependencyObject obj, bool value)
        {
            obj.SetValue(IsDragSelectingProperty, value);
        }

        public static readonly DependencyProperty IsDragSelectingProperty =
            DependencyProperty.RegisterAttached("IsDragSelecting", typeof (bool), typeof (DragSelectionHelper),
                new UIPropertyMetadata(false, IsDragSelectingPropertyChanged));

        private static void IsDragSelectingPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            var listBoxItem = o as ListBoxItem;

            if (listBoxItem == null)
                return;

            if (!GetIsDragClickStarted(listBoxItem)) return;

            if (GetIsDragSelecting(listBoxItem))
            {
                listBoxItem.IsSelected = true;
            }
        }

        #endregion IsDragSelectingProperty

        #region IsDragClickStartedProperty

        public static bool GetIsDragClickStarted(DependencyObject obj)
        {
            return (bool) obj.GetValue(IsDragClickStartedProperty);
        }

        public static void SetIsDragClickStarted(DependencyObject obj, bool value)
        {
            obj.SetValue(IsDragClickStartedProperty, value);
        }

        public static readonly DependencyProperty IsDragClickStartedProperty =
            DependencyProperty.RegisterAttached("IsDragClickStarted", typeof (bool), typeof (DragSelectionHelper),
                new FrameworkPropertyMetadata(false, IsDragClickStartedPropertyChanged) {Inherits = true});

        private static void IsDragClickStartedPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            var listBox = obj as ListBox;

            if (listBox == null)
                return;

            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
                return;

            var hitTestResult = VisualTreeHelper.HitTest(listBox, Mouse.GetPosition(listBox));
            if (hitTestResult == null)
                return;

            var element = hitTestResult.VisualHit;
            while (element != null)
            {
                var scrollBar = element as ScrollBar;
                if (scrollBar != null)
                {
                    return;
                }
                element = VisualTreeHelper.GetParent(element);
            }

            if (GetIsDragClickStarted(listBox))
                listBox.SelectedItems.Clear();
        }

        #endregion IsDragClickInitiatedProperty
    }
}


1 commentaires

Merci! C'était presque une copie et une pâte, à l'exception de l'espace de noms modifié qui a généré des erreurs (et la petite section "Windows partielle publique1: fenêtre" au début)