누구든지이 작업을 수행하는 방법에 대한 아이디어가 있는지 궁금 할 것입니다. 사용자가 마우스를 클릭하고 드래그하여 여러 항목을 선택할 수있게하고 싶습니다. 사용자가 항목 1을 클릭 한 다음 항목 10으로 아래로 끕니다. 1 번 항목을 클릭 한 다음 10 번 항목을 Shift + 클릭 한 것처럼 1 번부터 10 번 항목을 선택해야합니다.wpf listview 여러 항목을 선택하여 끌기
감사합니다.
누구든지이 작업을 수행하는 방법에 대한 아이디어가 있는지 궁금 할 것입니다. 사용자가 마우스를 클릭하고 드래그하여 여러 항목을 선택할 수있게하고 싶습니다. 사용자가 항목 1을 클릭 한 다음 항목 10으로 아래로 끕니다. 1 번 항목을 클릭 한 다음 10 번 항목을 Shift + 클릭 한 것처럼 1 번부터 10 번 항목을 선택해야합니다.wpf listview 여러 항목을 선택하여 끌기
감사합니다.
내 솔루션은 ListView의 PreviewLeftMouseButtonDown 및 MouseLeftButtonUp을 처리하는 도우미 클래스를 만들고 ListViewItems의 작은 스타일은 마우스를 가리면 헬퍼 클래스를 나타내므로 선택 여부를 결정할 수 있습니다. 항목 (마우스 왼쪽 버튼을 누르거나 누르지 않았을 때).
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에서 스타일을 추가하고, 세트 어쨌든, 여기에 전체 프로젝트의 :
지역 : 패에 DragSelectionHelper.IsDragSelectionEnabled = "true"로
연결된 속성 istView, 그리고 그것은 모든 것을 다룰 것입니다.
감사합니다.
SelectionMode=Extended
으로 사용자가 마우스 버튼을 누르기 전에 SHIFT 키를 누르고있는 경우 이미 가능합니다.
Carlo의 대답에 따라 코드 일부가 수정되었으므로 CTRL을 사용하여 현재 선택을 지우지 않고 계속 선택하고 SHIFT를 사용하여 '확장'모드와 같은 항목을 선택할 수 있습니다.
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
}
}
데모 : 나는 그것을 해결
감사합니다. 오류를 생성 한 변경된 네임 스페이스를 제외하고는 거의 복사하여 붙여 넣기였습니다 (시작 부분에 작은 부분 인 "public partial class Window1 : Window"). – TripleAntigen
, 나중에 솔루션을 게시합니다. 감사. – Carlo
나는이 질문에 대한 새로운 솔루션을 [WPF 드래그 앤 드롭으로 ListBox에서 SelectionMode Multiple] (http://stackoverflow.com/questions/1553622/wpf-drag-drop-from-listbox-with-selectionmode)에 게시했습니다. -배수). –