Saltar al contenido

wpf listview arrastrar seleccionar varios elementos

Hemos estado buscando por diferentes espacios para así mostrarte la solución para tu duda, si continúas con inquietudes déjanos la inquietud y contestamos porque estamos para ayudarte.

Solución:

Ok, aquí está mi solución, creé una clase auxiliar que maneja PreviewLeftMouseButtonDown y MouseLeftButtonUp para ListView, y un estilo pequeño para ListViewItems que cuando el mouse está sobre indica la clase auxiliar, por lo que puede decidir si selecciona el elemento o no (basado en que se presione o no el botón izquierdo del mouse). De todos modos, aquí está el proyecto completo:

XAML:


    

        

    

    
        
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
    

C#:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace DragSelectListBox

    /// 
    /// Interaction logic for Window1.xaml
    /// 
    public partial class Window1 : Window
    
        public Window1()
        
            InitializeComponent();
        
    

    // CARLO 20100519: Helper class for DragSelection
    public class DragSelectionHelper : DependencyObject
    
        #region Random Static Properties

        // need a static reference to the listbox otherwise it can't be accessed
            // (this only happened in the project I'm working on, if you're using a regular ListBox, with regular ListBoxItems you can get the ListBox from the ListBoxItems)
        public static ListBox ListBox  get; private set; 

        #endregion Random Static Properties

        #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));

        public static void IsDragSelectingEnabledPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        
            ListBox listBox = o as ListBox;

            bool isDragSelectionEnabled = DragSelectionHelper.GetIsDragSelectionEnabled(listBox);

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

                // set the static listbox property
                DragSelectionHelper.ListBox = listBox;

                // and subscribe to the required events to handle the drag selection and the attached properties
                listBox.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DragSelectionHelper.listBox_PreviewMouseLeftButtonDown);
                listBox.PreviewMouseRightButtonDown += new MouseButtonEventHandler(listBox_PreviewMouseRightButtonDown);
                listBox.MouseLeftButtonUp += new MouseButtonEventHandler(DragSelectionHelper.listBox_MouseLeftButtonUp);
            
            else // is selection is disabled
            
                // set selection mode to the default
                listBox.SelectionMode = SelectionMode.Single;

                // dereference the listbox
                DragSelectionHelper.ListBox = null;

                // unsuscribe from the events
                listBox.PreviewMouseLeftButtonDown -= new MouseButtonEventHandler(DragSelectionHelper.listBox_PreviewMouseLeftButtonDown);
                listBox.MouseLeftButtonUp -= new MouseButtonEventHandler(DragSelectionHelper.listBox_MouseLeftButtonUp);
                listBox.MouseLeftButtonUp -= new MouseButtonEventHandler(DragSelectionHelper.listBox_MouseLeftButtonUp);
            
        

        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)
        
            // notify the helper class that the listbox has initiated the drag click
            DragSelectionHelper.SetIsDragClickStarted(DragSelectionHelper.ListBox, true);
        

        private static void listBox_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        
            // notify the helper class that the list box has terminated the drag click
            DragSelectionHelper.SetIsDragClickStarted(DragSelectionHelper.ListBox, false);
        

        #endregion IsDragSelectionEnabledProperty

        #region IsDragSelectinProperty

        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));

        public static void IsDragSelectingPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        
            ListBoxItem item = o as ListBoxItem;

            bool clickInitiated = DragSelectionHelper.GetIsDragClickStarted(DragSelectionHelper.ListBox);

            // this is where the item.Parent was null, it was supposed to be the ListBox, I guess it's null because items are not
            // really ListBoxItems but are wells
            if (clickInitiated)
            
                bool isDragSelecting = DragSelectionHelper.GetIsDragSelecting(item);

                if (isDragSelecting)
                
                    // using the ListBox static reference because could not get to it through the item.Parent property
                    DragSelectionHelper.ListBox.SelectedItems.Add(item);
                
            
        

        #endregion IsDragSelectinProperty

        #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 UIPropertyMetadata(false, IsDragClickStartedPropertyChanged));

        public static void IsDragClickStartedPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        
            bool isDragClickStarted = DragSelectionHelper.GetIsDragClickStarted(DragSelectionHelper.ListBox);

            // if click has been drag click has started, clear the current selected items and start drag selection operation again
            if (isDragClickStarted)
                DragSelectionHelper.ListBox.SelectedItems.Clear();
        

        #endregion IsDragClickInitiatedProperty
    

Como puede ver, todo lo que necesita hacer es agregar el estilo en su xaml y establecer:

local: DragSelectionHelper.IsDragSelectionEnabled = “true”

Propiedad adjunta a ListView, y eso se encargará de todo.

¡Gracias!

Basado en la respuesta de Carlo, modifiqué parte de su código, ahora puede usar CTRL para continuar seleccionando sin borrar la selección actual, y usar SHIFT para seleccionar elementos como el modo ‘Extendido’.

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 

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

            if (e.Key == Key.LeftShift 

        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)
        

        #endregion IsDragClickInitiatedProperty
    

Manifestación:
Manifestación

También tenga en cuenta que con SelectionMode=Extended esto ya es posible, si el usuario mantiene presionada la CAMBIO antes de presionar el botón del mouse.

Nos encantaría que puedieras dar visibilidad a este enunciado si te ayudó.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)


Tags : / /

Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *