先上效果图:
关键代码:
1 public partial class Window1 : System.Windows.Window 2 { 3 ListViewDragDropManager<Task> dragMgr; 4 ListViewDragDropManager<Task> dragMgr2; 5 6 public Window1() 7 { 8 InitializeComponent(); 9 this.Loaded += Window1_Loaded; 10 } 11 12 #region Window1_Loaded 13 14 void Window1_Loaded( object sender, RoutedEventArgs e ) 15 { 16 // Give the ListView an ObservableCollection of Task 17 // as a data source. Note, the ListViewDragManager MUST 18 // be bound to an ObservableCollection, where the collection's 19 // type parameter matches the ListViewDragManager's type 20 // parameter (in this case, both have a type parameter of Task). 21 ObservableCollection<Task> tasks = Task.CreateTasks(); 22 this.listView.ItemsSource = tasks; 23 24 this.listView2.ItemsSource = new ObservableCollection<Task>(); 25 26 // This is all that you need to do, in order to use the ListViewDragManager. 27 this.dragMgr = new ListViewDragDropManager<Task>( this.listView ); 28 this.dragMgr2 = new ListViewDragDropManager<Task>( this.listView2 ); 29 30 // Turn the ListViewDragManager on and off. 31 this.chkManageDragging.Checked += delegate { this.dragMgr.ListView = this.listView; }; 32 this.chkManageDragging.Unchecked += delegate { this.dragMgr.ListView = null; }; 33 34 // Show and hide the drag adorner. 35 this.chkDragAdorner.Checked += delegate { this.dragMgr.ShowDragAdorner = true; }; 36 this.chkDragAdorner.Unchecked += delegate { this.dragMgr.ShowDragAdorner = false; }; 37 38 // Change the opacity of the drag adorner. 39 this.sldDragOpacity.ValueChanged += delegate { this.dragMgr.DragAdornerOpacity = this.sldDragOpacity.Value; }; 40 41 // Apply or remove the item container style, which responds to changes 42 // in the attached properties of ListViewItemDragState. 43 this.chkApplyContStyle.Checked += delegate { this.listView.ItemContainerStyle = this.FindResource( "ItemContStyle" ) as Style; }; 44 this.chkApplyContStyle.Unchecked += delegate { this.listView.ItemContainerStyle = null; }; 45 46 // Use or do not use custom drop logic. 47 this.chkSwapDroppedItem.Checked += delegate { this.dragMgr.ProcessDrop += dragMgr_ProcessDrop; }; 48 this.chkSwapDroppedItem.Unchecked += delegate { this.dragMgr.ProcessDrop -= dragMgr_ProcessDrop; }; 49 50 // Show or hide the lower ListView. 51 this.chkShowOtherListView.Checked += delegate { this.listView2.Visibility = Visibility.Visible; }; 52 this.chkShowOtherListView.Unchecked += delegate { this.listView2.Visibility = Visibility.Collapsed; }; 53 54 // Hook up events on both ListViews to that we can drag-drop 55 // items between them. 56 this.listView.DragEnter += OnListViewDragEnter; 57 this.listView2.DragEnter += OnListViewDragEnter; 58 this.listView.Drop += OnListViewDrop; 59 this.listView2.Drop += OnListViewDrop; 60 } 61 62 #endregion // Window1_Loaded 63 64 #region dragMgr_ProcessDrop 65 66 // Performs custom drop logic for the top ListView. 67 void dragMgr_ProcessDrop( object sender, ProcessDropEventArgs<Task> e ) 68 { 69 // This shows how to customize the behavior of a drop. 70 // Here we perform a swap, instead of just moving the dropped item. 71 72 int higherIdx = Math.Max( e.OldIndex, e.NewIndex ); 73 int lowerIdx = Math.Min( e.OldIndex, e.NewIndex ); 74 75 if( lowerIdx < 0 ) 76 { 77 // The item came from the lower ListView 78 // so just insert it. 79 e.ItemsSource.Insert( higherIdx, e.DataItem ); 80 } 81 else 82 { 83 // null values will cause an error when calling Move. 84 // It looks like a bug in ObservableCollection to me. 85 if( e.ItemsSource[lowerIdx] == null || 86 e.ItemsSource[higherIdx] == null ) 87 return; 88 89 // The item came from the ListView into which 90 // it was dropped, so swap it with the item 91 // at the target index. 92 e.ItemsSource.Move( lowerIdx, higherIdx ); 93 e.ItemsSource.Move( higherIdx - 1, lowerIdx ); 94 } 95 96 // Set this to 'Move' so that the OnListViewDrop knows to 97 // remove the item from the other ListView. 98 e.Effects = DragDropEffects.Move; 99 } 100 101 #endregion // dragMgr_ProcessDrop 102 103 #region OnListViewDragEnter 104 105 // Handles the DragEnter event for both ListViews. 106 void OnListViewDragEnter( object sender, DragEventArgs e ) 107 { 108 e.Effects = DragDropEffects.Move; 109 } 110 111 #endregion // OnListViewDragEnter 112 113 #region OnListViewDrop 114 115 // Handles the Drop event for both ListViews. 116 void OnListViewDrop( object sender, DragEventArgs e ) 117 { 118 if( e.Effects == DragDropEffects.None ) 119 return; 120 121 Task task = e.Data.GetData( typeof( Task ) ) as Task; 122 if( sender == this.listView ) 123 { 124 if( this.dragMgr.IsDragInProgress ) 125 return; 126 127 // An item was dragged from the bottom ListView into the top ListView 128 // so remove that item from the bottom ListView. 129 (this.listView2.ItemsSource as ObservableCollection<Task>).Remove( task ); 130 } 131 else 132 { 133 if( this.dragMgr2.IsDragInProgress ) 134 return; 135 136 // An item was dragged from the top ListView into the bottom ListView 137 // so remove that item from the top ListView. 138 (this.listView.ItemsSource as ObservableCollection<Task>).Remove( task ); 139 } 140 } 141 142 #endregion // OnListViewDrop 143 144 }
1 <Window x:Class="ListViewDragDropManagerDemo.Window1" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:jas="clr-namespace:WPF.JoshSmith.ServiceProviders.UI" 5 Title="ListViewDragDropManager Demo" Height="600" Width="700" 6 FontSize="12" 7 WindowStartupLocation="CenterScreen" 8 > 9 <Window.Resources> 10 <Style x:Key="ItemContStyle" TargetType="ListViewItem"> 11 <Style.Resources> 12 <LinearGradientBrush x:Key="MouseOverBrush" StartPoint="0.5, 0" EndPoint="0.5, 1"> 13 <GradientStop Color="#22000000" Offset="0" /> 14 <GradientStop Color="#44000000" Offset="0.4" /> 15 <GradientStop Color="#55000000" Offset="0.6" /> 16 <GradientStop Color="#33000000" Offset="0.9" /> 17 <GradientStop Color="#22000000" Offset="1" /> 18 </LinearGradientBrush> 19 </Style.Resources> 20 <Setter Property="Padding" Value="0,4" /> 21 <Setter Property="HorizontalContentAlignment" Value="Stretch" /> 22 <!-- The default control template for ListViewItem has a Border 23 which contains the item's content. --> 24 <Setter Property="Border.BorderThickness" Value="0,0,0,0.5" /> 25 <Setter Property="Border.BorderBrush" Value="LightGray" /> 26 <!-- These triggers react to changes in the attached properties set 27 during a managed drag-drop operation. --> 28 <Style.Triggers> 29 <Trigger Property="jas:ListViewItemDragState.IsBeingDragged" Value="True"> 30 <Setter Property="FontWeight" Value="DemiBold" /> 31 </Trigger> 32 <Trigger Property="jas:ListViewItemDragState.IsUnderDragCursor" Value="True"> 33 <Setter Property="Background" Value="{StaticResource MouseOverBrush}" /> 34 </Trigger> 35 </Style.Triggers> 36 </Style> 37 </Window.Resources> 38 39 <Grid> 40 <Grid.RowDefinitions> 41 <RowDefinition Height="Auto" /> 42 <RowDefinition Height="*" /> 43 <RowDefinition Height="Auto" /> 44 </Grid.RowDefinitions> 45 46 <GroupBox Header="Main ListView Settings" Grid.Row="0" Margin="4" Padding="2"> 47 <StackPanel> 48 <StackPanel.Resources> 49 <Style TargetType="CheckBox"> 50 <Setter Property="HorizontalAlignment" Value="Left" /> 51 <Setter Property="IsChecked" Value="True" /> 52 </Style> 53 </StackPanel.Resources> 54 <CheckBox 55 Name="chkManageDragging" 56 Margin="4" 57 > 58 Manage Dragging of ListViewItems 59 </CheckBox> 60 <StackPanel Margin="4" IsEnabled="{Binding ElementName=chkManageDragging, Path=IsChecked}"> 61 <CheckBox 62 Name="chkDragAdorner" 63 Margin="0,4" 64 > 65 Show Drag Adorner 66 </CheckBox> 67 <StackPanel Orientation="Horizontal" Margin="0,4" IsEnabled="{Binding ElementName=chkDragAdorner, Path=IsChecked}"> 68 <Label>Drag Adorner Opacity:</Label> 69 <Slider Name="sldDragOpacity" Value="0.7" Minimum="0" Maximum="1" Width="90" Margin="4" /> 70 <Label Content="{Binding ElementName=sldDragOpacity, Path=Value}" /> 71 </StackPanel> 72 </StackPanel> 73 <Line Stroke="DarkGray" Stretch="Fill" StrokeThickness="0.5" X1="0" X2="1" /> 74 <CheckBox 75 Name="chkApplyContStyle" 76 Margin="4,8,4,4" 77 ToolTip="If checked, the ListView's ItemContainerStyle is set to a Style which reacts to the drag operation." 78 > 79 Apply Item Container Style 80 </CheckBox> 81 <CheckBox 82 Name="chkSwapDroppedItem" 83 IsChecked="False" 84 Margin="4" 85 ToolTip="If checked, the dropped item and the item at the target index will exchange locations." 86 > 87 Use Custom Drop Logic 88 </CheckBox> 89 <CheckBox 90 Name="chkShowOtherListView" 91 IsChecked="False" 92 Margin="4" 93 ToolTip="If checked, another ListView is visible. The items from one ListView can be dropped into the other ListView." 94 > 95 Show Other ListView 96 </CheckBox> 97 </StackPanel> 98 </GroupBox> 99 100 <ListView Name="listView" 101 Grid.Row="1" 102 ItemContainerStyle="{StaticResource ItemContStyle}" 103 Margin="4" 104 Padding="2" 105 SelectionMode="Single" 106 > 107 <ListView.View> 108 <GridView> 109 <GridViewColumn Header="Finished"> 110 <GridViewColumn.CellTemplate> 111 <DataTemplate> 112 <CheckBox IsChecked="{Binding Finished}" HorizontalAlignment="Center" /> 113 </DataTemplate> 114 </GridViewColumn.CellTemplate> 115 </GridViewColumn> 116 <GridViewColumn Header="Duration" DisplayMemberBinding="{Binding Duration}" Width="80" /> 117 <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="175" /> 118 <GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" Width="340" /> 119 </GridView> 120 </ListView.View> 121 </ListView> 122 123 <ListView Name="listView2" 124 Grid.Row="2" 125 Height="185" 126 ItemContainerStyle="{StaticResource ItemContStyle}" 127 Margin="4" 128 Padding="2" 129 SelectionMode="Single" 130 Visibility="Collapsed" 131 > 132 <ListView.View> 133 <GridView> 134 <GridViewColumn Header="Finished"> 135 <GridViewColumn.CellTemplate> 136 <DataTemplate> 137 <CheckBox IsChecked="{Binding Finished}" HorizontalAlignment="Center" /> 138 </DataTemplate> 139 </GridViewColumn.CellTemplate> 140 </GridViewColumn> 141 <GridViewColumn Header="Duration" DisplayMemberBinding="{Binding Duration}" Width="80" /> 142 <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="175" /> 143 <GridViewColumn Header="Description" DisplayMemberBinding="{Binding Description}" Width="340" /> 144 </GridView> 145 </ListView.View> 146 </ListView> 147 </Grid> 148 </Window>
源码下载地址:http://files.cnblogs.com/zhangyongheng/ListViewDragDropManager_src.zip
转自:http://www.codeproject.com/Articles/17266/Drag-and-Drop-Items-in-a-WPF-ListView