WPF列表视图拖动选择多个项目 [英] wpf listview drag select multiple items

查看:96
本文介绍了WPF列表视图拖动选择多个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

只是想知道如果任何人有如何做到这一点的想法。我希望让用户选择通过单击并拖动鼠标多个项目(同时不让点击GO)。假设用户点击第1项,然后拖累项目10;项目1到10应该得到选择的,如果他点击第1项,然后按Shift +点击物品10。

Just wondering if anyone has any idea on how to do this. I want to let the user select multiple items by clicking and dragging the mouse (without letting the click go). Say the user clicks on item 1, then drags down to item 10; item 1 through 10 should get selected as if he clicked item 1, then shift + clicked on item 10.

让我知道,谢谢!

推荐答案

确定这里是我的解决方案,我创建了处理previewLeftMouseButtonDown和的MouseLeftButtonUp为ListView一个辅助类,和一个小样式的ListViewItems当鼠标移动到它表明辅助类,因此,如果选择项目或不是就可以决定(基于pssed与否鼠标左键存在$ P $)。总之,这里的完整的项目:

Ok here's my solution, I created a helper class that handles the PreviewLeftMouseButtonDown and MouseLeftButtonUp for the ListView, and a small style for the ListViewItems that when the mouse is over it indicates the helper class, so it can decide if it selects the item or not (based on the mouse left button being pressed or not). Anyway, here's the full project:

XAML:

<Window x:Class="DragSelectListBox.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DragSelectListBox"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>

        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="local:DragSelectionHelper.IsDragSelecting" Value="False" />
            <Style.Triggers>
                <Trigger Property="ListBoxItem.IsMouseOver" Value="True">
                    <Setter Property="local:DragSelectionHelper.IsDragSelecting" Value="True" />
                </Trigger>
            </Style.Triggers>
        </Style>

    </Window.Resources>

    <Grid Background="AliceBlue">
        <ListBox Margin="8"
                 local:DragSelectionHelper.IsDragSelectionEnabled="true">
            <ListBoxItem Content="Item 1" />
            <ListBoxItem Content="Item 2" />
            <ListBoxItem Content="Item 3" />
            <ListBoxItem Content="Item 4" />
            <ListBoxItem Content="Item 5" />
            <ListBoxItem Content="Item 6" />
            <ListBoxItem Content="Item 7" />
            <ListBoxItem Content="Item 8" />
            <ListBoxItem Content="Item 9" />
            <ListBoxItem Content="Item 10" />
            <ListBoxItem Content="Item 11" />
            <ListBoxItem Content="Item 12" />
            <ListBoxItem Content="Item 13" />
            <ListBoxItem Content="Item 14" />
            <ListBoxItem Content="Item 15" />
            <ListBoxItem Content="Item 16" />
            <ListBoxItem Content="Item 17" />
            <ListBoxItem Content="Item 18" />
            <ListBoxItem Content="Item 19" />
            <ListBoxItem Content="Item 20" />
            <ListBoxItem Content="Item 21" />
            <ListBoxItem Content="Item 22" />
            <ListBoxItem Content="Item 23" />
            <ListBoxItem Content="Item 24" />
            <ListBoxItem Content="Item 25" />
            <ListBoxItem Content="Item 26" />
            <ListBoxItem Content="Item 27" />
            <ListBoxItem Content="Item 28" />
            <ListBoxItem Content="Item 29" />
            <ListBoxItem Content="Item 30" />
        </ListBox>
    </Grid>
</Window>

C#:

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

namespace DragSelectListBox
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    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
    }
}

因此​​,大家可以看到,所有你需要做的就是添加的风格在你的XAML,并设置:

So as you can see, all you need to do is add the style in your xaml, and set the:

本地:DragSelectionHelper.IsDragSelectionEnabled =真正的

local:DragSelectionHelper.IsDragSelectionEnabled="true"

附加属性到ListView,那会照顾一切。

Attached property to the ListView, and that'll take care of everything.

谢谢!

这篇关于WPF列表视图拖动选择多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆