ListView控件的拖放排序功能实现

在WPF应用程序中,ListView控件是展示数据列表的常用组件。为了提升用户体验,经常需要实现一些交互功能,比如拖放排序。本文将详细介绍如何在ListView控件中实现拖放排序功能,包括XAML布局和C#后端代码的编写。

概述

拖放排序功能允许用户通过拖动列表项来重新排序列表。在WPF中,这可以通过设置ListView的AllowDrop属性为True,并处理相关的拖放事件来实现。下面将分步骤介绍如何实现这一功能。

创建项目和布局

首先,需要创建一个新的WPF项目,并在XAML代码编辑器中定义主窗口。将添加两个按钮和一个ListView对象。ListView对象需要设置AllowDrop属性为True,以启用拖放功能。

<Button x:Name="btnUp" Content="向上移动" HorizontalAlignment="Left" Height="28" Margin="10,12,0,0" VerticalAlignment="Top" Width="68" Click="btnUp_Click" /> <Button x:Name="btnDown" Content="向下移动" HorizontalAlignment="Left" Height="28" Margin="83,12,0,0" VerticalAlignment="Top" Width="68" Click="btnDown_Click" /> <ListView Margin="10,50,10,10" Name="lstView" BorderBrush="WhiteSmoke" AllowDrop="True" PreviewMouseLeftButtonDown="lstView_PreviewMouseLeftButtonDown" MouseMove="lstView_MouseMove" DragEnter="lstView_DragEnter" Drop="lstView_Drop"> <ListView.View> <GridView> <GridViewColumn Header="选择" Width="32"> <GridViewColumn.CellTemplate> <DataTemplate> <CheckBox IsChecked="{Binding IsSelected}" /> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="标题" Width="120" DisplayMemberBinding="{Binding Title}" /> <GridViewColumn Header="备注" Width="150" DisplayMemberBinding="{Binding Note}" /> </GridView> </ListView.View> </ListView>

这段XAML代码需要插入到<Grid></Grid>数据块之间。

定义数据模型

接下来,需要定义一个数据模型来表示ListView中的数据项。将创建一个名为WorkItem的类,并添加相应的属性。

public class WorkItem { public bool IsSelected { get; set; } public string Title { get; set; } public string Note { get; set; } public WorkItem(bool isSelected, string title, string note) { this.IsSelected = isSelected; this.Title = title; this.Note = note; } }

这个类代表了ListView对象的数据项。为了显示自定义项,需要修改WorkItem类的属性和XAML代码,以定义数据列和正确的数据绑定到自定义类。

初始化ListView

在主窗口的代码编辑器中,需要添加一些代码来初始化ListView控件。将使用ObservableCollection对象来管理项目列表,因为它提供了一些方法,使得在集合中移动项目变得更加容易。

private Point startPoint = new Point(); private ObservableCollection<WorkItem> Items = new ObservableCollection<WorkItem>(); private int startIndex = -1; private void InitializeListView() { lstView.Items.Clear(); Items.Clear(); Items.Add(new WorkItem(true, "第一行", "第一行内容")); Items.Add(new WorkItem(false, "第二行", "第二行内容")); Items.Add(new WorkItem(true, "第三行", "第三行内容")); lstView.ItemsSource = Items; }

在类构造函数中,调用InitializeListView()函数来初始化ListView控件。

实现拖放事件

为了实现拖放排序功能,需要处理一些事件。使用btnUp和btnDown按钮,可以在ListView控件中移动选定的项目,而不需要使用拖放功能。

private void lstView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { startPoint = e.GetPosition(null); } private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject { do { if (current is T) { return (T)current; } current = VisualTreeHelper.GetParent(current); } while (current != null); return null; } private void lstView_MouseMove(object sender, MouseEventArgs e) { Point mousePos = e.GetPosition(null); Vector diff = startPoint - mousePos; if (e.LeftButton == MouseButtonState.Pressed && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)) { ListView listView = sender as ListView; ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource); if (listViewItem == null) return; WorkItem item = (WorkItem)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); if (item == null) return; startIndex = lstView.SelectedIndex; DataObject dragData = new DataObject("WorkItem", item); DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move); } } private void lstView_DragEnter(object sender, DragEventArgs e) { if (!e.Data.GetDataPresent("WorkItem") || sender != e.Source) { e.Effects = DragDropEffects.None; } } private void lstView_Drop(object sender, DragEventArgs e) { int index = -1; if (e.Data.GetDataPresent("WorkItem") && sender == e.Source) { ListView listView = sender as ListView; ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource); if (listViewItem == null) { e.Effects = DragDropEffects.None; return; } WorkItem item = (WorkItem)listView.ItemContainerGenerator.ItemFromContainer(listViewItem); index = Items.IndexOf(item); e.Effects = DragDropEffects.Move; if (startIndex >= 0 && index >= 0) { Items.Move(startIndex, index); } startIndex = -1; } } private void btnUp_Click(object sender, RoutedEventArgs e) { WorkItem item = null; int index = -1; if (lstView.SelectedItems.Count != 1) return; item = (WorkItem)lstView.SelectedItems[0]; index = Items.IndexOf(item); if (index > 0) { Items.Move(index, index - 1); } } private void btnDown_Click(object sender, RoutedEventArgs e) { WorkItem item = null; int index = -1; if (lstView.SelectedItems.Count != 1) return; item = (WorkItem)lstView.SelectedItems[0]; index = Items.IndexOf(item); if (index < Items.Count - 1) { Items.Move(index, index + 1); } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485