ListBox实现拖拽排序功能
1、拖拽需要实现的事件包括:
PreviewMouseLeftButtonDown
LBoxSort_OnDrop
具体实现如下:

private void LBoxSort_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { var pos = e.GetPosition(LBoxSort); HitTestResult result = VisualTreeHelper.HitTest(LBoxSort, pos); if (result == null) { return; } var listBoxItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit); if (listBoxItem == null || listBoxItem.Content != LBoxSort.SelectedItem) { return; } DataObject dataObj = new DataObject(listBoxItem.Content as Person); DragDrop.DoDragDrop(LBoxSort, dataObj, DragDropEffects.Move); } private void LBoxSort_OnDrop(object sender, DragEventArgs e) { var pos = e.GetPosition(LBoxSort); var result = VisualTreeHelper.HitTest(LBoxSort, pos); if (result == null) { return; } //查找元数据 var sourcePerson = e.Data.GetData(typeof (Person)) as Person; if (sourcePerson == null) { return; } //查找目标数据 var listBoxItem = Utils.FindVisualParent<ListBoxItem>(result.VisualHit); if (listBoxItem == null) { return; } var targetPerson = listBoxItem.Content as Person; if (ReferenceEquals(targetPerson, sourcePerson)) { return; } _persons.Remove(sourcePerson); _persons.Insert(_persons.IndexOf(targetPerson), sourcePerson); } }
2、排序功能实现:
数据源:

private ObservableCollection<Person> _persons = new ObservableCollection<Person>(); private void InitData() { _persons.Add(new Person{Name = "test1", Order = "1"}); _persons.Add(new Person { Name = "test2", Order = "2" }); _persons.Add(new Person { Name = "test3", Order = "3" }); _persons.Add(new Person { Name = "test4", Order = "4" }); _persons.Add(new Person { Name = "test5", Order = "5" }); }
3、排序功能实现:
为数据集合实现CollectionChanged事件,当数据集合发生变化时执行:

private void PersonsOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Remove) { for (int i = e.OldStartingIndex; i < _persons.Count; i++) { _persons[i].Order = i.ToString(); } } else if (e.Action == NotifyCollectionChangedAction.Add) { for (int i = e.NewStartingIndex; i < _persons.Count; i++) { _persons[i].Order = i.ToString(); } } }
4、相关代码附加:

public class Person : INotifyPropertyChanged { public string Name { get; set; } private string _order; public string Order { get { return _order; } set { _order = value; OnPropertyChanged("Order"); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } internal static class Utils { //根据子元素查找父元素 public static T FindVisualParent<T>(DependencyObject obj) where T : class { while (obj != null) { if (obj is T) return obj as T; obj = VisualTreeHelper.GetParent(obj); } return null; } }
5、代码下载地址:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~