mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 21:55:34 +08:00
extended ListView with multiple items selection.
This commit is contained in:
parent
209d98aea6
commit
9dd07eea06
182
ListViewEx.cs
Normal file
182
ListViewEx.cs
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
//! \file ListViewEx.cs
|
||||||
|
//! \date Thu Jul 24 02:19:38 2014
|
||||||
|
//! \brief Extended ListView with explorer-like multiple items selection.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 by morkt
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to
|
||||||
|
// deal in the Software without restriction, including without limitation the
|
||||||
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
// IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace GARbro.GUI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This Extended ListView allows selecting multiple items by dragging mouse over them.
|
||||||
|
/// </summary>
|
||||||
|
public class ListViewEx : ListView
|
||||||
|
{
|
||||||
|
public bool SelectionActive { get; set; }
|
||||||
|
public ListViewItem LastSelectedItem { get; set; }
|
||||||
|
|
||||||
|
public ListViewEx ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override DependencyObject GetContainerForItemOverride()
|
||||||
|
{
|
||||||
|
return new ListViewItemEx();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeftButtonDown (MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (0 == (Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)))
|
||||||
|
{
|
||||||
|
StartDragSelect();
|
||||||
|
}
|
||||||
|
base.OnMouseLeftButtonDown (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeftButtonUp (MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (SelectionActive)
|
||||||
|
{
|
||||||
|
EndDragSelect();
|
||||||
|
}
|
||||||
|
base.OnMouseLeftButtonUp (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeave (MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (SelectionActive)
|
||||||
|
{
|
||||||
|
EndDragSelect();
|
||||||
|
}
|
||||||
|
base.OnMouseLeave (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnItemsSourceChanged (IEnumerable oldValue, IEnumerable newValue)
|
||||||
|
{
|
||||||
|
if (SelectionActive)
|
||||||
|
{
|
||||||
|
EndDragSelect();
|
||||||
|
}
|
||||||
|
base.OnItemsSourceChanged (oldValue, newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void StartDragSelect ()
|
||||||
|
{
|
||||||
|
SelectionActive = true;
|
||||||
|
SelectedItems.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void EndDragSelect ()
|
||||||
|
{
|
||||||
|
SelectionActive = false;
|
||||||
|
LastSelectedItem = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void ContinueDragSelect (ListViewItem addition)
|
||||||
|
{
|
||||||
|
if (null != LastSelectedItem)
|
||||||
|
{
|
||||||
|
int start = ItemContainerGenerator.IndexFromContainer (LastSelectedItem);
|
||||||
|
int end = ItemContainerGenerator.IndexFromContainer (addition);
|
||||||
|
if (start != -1 && end != -1)
|
||||||
|
{
|
||||||
|
if (start > end)
|
||||||
|
{
|
||||||
|
int index = start;
|
||||||
|
start = end;
|
||||||
|
end = index;
|
||||||
|
}
|
||||||
|
// for each item in the range [start, end]
|
||||||
|
foreach (var item in Items.Cast<object>().Skip (start).Take (end-start+1))
|
||||||
|
{
|
||||||
|
var lvi = (ListViewItem)ItemContainerGenerator.ContainerFromItem (item);
|
||||||
|
if (!lvi.IsSelected)
|
||||||
|
lvi.IsSelected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!addition.IsSelected)
|
||||||
|
addition.IsSelected = true;
|
||||||
|
LastSelectedItem = addition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListViewItemEx : ListViewItem
|
||||||
|
{
|
||||||
|
private ListViewEx ParentListView
|
||||||
|
{
|
||||||
|
get { return ItemsControl.ItemsControlFromItemContainer (this) as ListViewEx; }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPreviewMouseLeftButtonDown (MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
var lv = ParentListView;
|
||||||
|
if (null != lv)
|
||||||
|
{
|
||||||
|
if (0 == (Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)))
|
||||||
|
{
|
||||||
|
lv.StartDragSelect();
|
||||||
|
lv.ContinueDragSelect (this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base.OnPreviewMouseLeftButtonDown(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPreviewMouseLeftButtonUp (MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
var lv = ParentListView;
|
||||||
|
if (null != lv && lv.SelectionActive)
|
||||||
|
{
|
||||||
|
lv.EndDragSelect();
|
||||||
|
}
|
||||||
|
base.OnPreviewMouseLeftButtonUp(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseDoubleClick (MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
var lv = ParentListView;
|
||||||
|
if (null != lv && lv.SelectionActive)
|
||||||
|
{
|
||||||
|
lv.EndDragSelect();
|
||||||
|
}
|
||||||
|
base.OnMouseDoubleClick (e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseEnter (MouseEventArgs e)
|
||||||
|
{
|
||||||
|
var lv = ParentListView;
|
||||||
|
if (null != lv && lv.SelectionActive)
|
||||||
|
{
|
||||||
|
lv.ContinueDragSelect (this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
base.OnMouseEnter (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -150,7 +150,7 @@
|
|||||||
<ColumnDefinition Width="1"/>
|
<ColumnDefinition Width="1"/>
|
||||||
<ColumnDefinition Width="*" MinWidth="100"/>
|
<ColumnDefinition Width="*" MinWidth="100"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<ListView x:Name="CurrentDirectory" Grid.Column="0"
|
<local:ListViewEx x:Name="CurrentDirectory" Grid.Column="0"
|
||||||
ItemsSource="{Binding Source={StaticResource ListViewSource}}"
|
ItemsSource="{Binding Source={StaticResource ListViewSource}}"
|
||||||
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
|
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
|
||||||
BorderBrush="Transparent" SelectedValuePath="Name"
|
BorderBrush="Transparent" SelectedValuePath="Name"
|
||||||
@ -233,7 +233,7 @@
|
|||||||
</GridViewColumn>
|
</GridViewColumn>
|
||||||
</GridView>
|
</GridView>
|
||||||
</ListView.View>
|
</ListView.View>
|
||||||
</ListView>
|
</local:ListViewEx>
|
||||||
<ScrollViewer Grid.Column="2" Background="LightGray"
|
<ScrollViewer Grid.Column="2" Background="LightGray"
|
||||||
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
|
||||||
<Image Name="PreviewPane" Stretch="None" UseLayoutRounding="False" SnapsToDevicePixels="True"
|
<Image Name="PreviewPane" Stretch="None" UseLayoutRounding="False" SnapsToDevicePixels="True"
|
||||||
|
Loading…
Reference in New Issue
Block a user