当前位置: 首页 > news >正文

WinUI3入门16:Order自定义排序

初级代码游戏的专栏介绍与文章目录-CSDN博客

我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。

这些代码大部分以Linux为目标但部分代码是纯C++的,可以在任何平台上使用。

源码指引:github源码指引_初级代码游戏的博客-CSDN博客

C#是我多年以来的业余爱好,新搞的东西能用C#的就用C#了。


        接上一篇继续研究排序问题。上一篇:WinUI3入门15:DataGrid排序-CSDN博客

        前一篇使用OrderBy对指定列排序,如果要同时对多列排序,或许可以用一串OrderBy来实现(因为OrderBy是稳定排序,如果相等,不会改变相对顺序)。

        但是首先写一串OrderBy相当繁琐,效果存在不确定性(依赖算法特性),其次多次排序性能可能存在问题,当然这都不是关键问题。

        关键问题是这不符合完全自定义这个目标。传统上(指C++)我们用传递一个比较函数(或函数对象)的方法来实现自定义的排序规则,在C#同样可以通过传递特定的接口来实现。

目录

一、Enumerable.Order 方法

二、ICompare

三、设计通用的比较接口


一、Enumerable.Order 方法

        ObservableCollection<>实现了IEnumerable<T> 接口,因此可以用Order方法进行排序。Order方法接受一个IComparer<T>参数:

public static System.Linq.IOrderedEnumerable<T> Order<T> (this System.Collections.Generic.IEnumerable<T> source, System.Collections.Generic.IComparer<T>? comparer);

        很明显这个ICompare<T>就是用作比较的方法,所以问题就归结为编写ICompare<T>。

二、ICompare<T>

        ICompare<T>要求如下:

public int Compare (T? x, T? y);

        这个我们看着很眼熟,返回值也很眼熟:0代表相等,大于0代表x>y,小于0代表x<y,跟我们传统的x-y是一样的。

三、设计通用的比较接口

        通常为了多列比较我们需要下面的信息:

  • 哪些列用作比较
  • 这些列的比较顺序(优先级)
  • 每个列的比较方法(字符串、数值、升序降序)

        因为这里是直接用属性比较,那么字符串还是数值是不需要额外记录的,所以要记住的就是列和升序降序,我们可以用下面的类来描述:

		public class SortColumn{public String name = "";public bool sortOrderAscending = true;//false Descending}

        再定义一个列表就可以描述列的顺序了:

		public List<SortColumn> sortColumns = new();

        现在我们考虑把描述规则放在一个类里,而具体的比较由类自身的方法来实现。理论上通过上一篇用的动态类型(PropertyInfo)处理是可以实现完美的通用比较类的,不过有时候自定义一下也没什么不好,可能更简单、更高效。

        整个通用部分如下:

	public interface IMyOrder<T> where T : IMyOrder<T>{int CompareTo(MyOrder<T> order, T tmp);}public class MyOrder<T> : System.Collections.Generic.IComparer<T> where T : IMyOrder<T> {public class SortColumn{public String name = "";public bool sortOrderAscending = true;//false Descending}public List<SortColumn> sortColumns = new();public MyOrder(){}//清除排序规则public void ClearSortColumn(){sortColumns.Clear();}//指定进行排序的列public void SetSortColumn(String colname){SortColumn? sortColumn = null;int index = -1;if (sortColumns.Count != 0){for (int i = 0; i < sortColumns.Count; ++i){SortColumn tmpColumn =sortColumns[i];if (tmpColumn.name == colname){sortColumn=tmpColumn;sortColumns.Remove(tmpColumn);index = i;}}}if (null == sortColumn){sortColumn = new SortColumn();sortColumn.name = colname;sortColumns.Add(sortColumn);}else{if (0 == index) sortColumn.sortOrderAscending = !sortColumn.sortOrderAscending;sortColumns.Insert(0, sortColumn);}}public int Compare(T? x, T? y){if(null==x && null==y)return 0;if (null == x) return -1;if(null==y)return 1;return x.CompareTo(this, y);}}

        前面定义了一个接口IMyOrder<T>用来由实际的数据实现比较函数。而MyOrder<T>的IComparer<T>的实现“public int Compare(T? x, T? y)”则调用IMyOrder<T>的CompareTo来实现真正的比较。

        最复杂的是SetSortColumn,要检查是否是已经存在的排序列,最新点击的排第一,如果连续点击第一个就改变正序逆序。

        数据那边则要增加对IMyOrder<T>的实现:

		public class Data : INotifyPropertyChanged, IMyOrder<Data>{。。。。。。public int CompareTo(MyOrder<Data> order,Data tmp){for (int i = 0; i < order.sortColumns.Count; ++i){int ret = 0;MyOrder<Data>.SortColumn sortColumn = order.sortColumns[i];if (sortColumn.name == "Dir") ret = _dir.CompareTo(tmp._dir);if (sortColumn.name == "File") ret = _file.CompareTo(tmp._file);if (sortColumn.name == "Ext") ret = _ext.CompareTo(tmp._ext);if (sortColumn.name == "Type") ret = _type.CompareTo(tmp._type);if (sortColumn.name == "Encode") ret = _encode.CompareTo(tmp._encode);if (sortColumn.name == "BOM") ret = _bom.CompareTo(tmp._bom);if (sortColumn.name == "CR") ret = _cr.CompareTo(tmp._cr);if (sortColumn.name == "CRLF") ret = _crlf.CompareTo(tmp._crlf);if (sortColumn.name == "LF") ret = _lf.CompareTo(tmp._lf);if (sortColumn.name == "Length") ret = _length.CompareTo(tmp._length);if (sortColumn.name == "State") ret = _state.CompareTo(tmp._state);if (!sortColumn.sortOrderAscending) ret = -ret;if (0 != ret) return ret;}return 0;}}

        主代码中的主要过程:

		MyOrder<Data> myOrder = new();//Sorting事件添加排序列myOrder.SetSortColumn(e.Column.Header.ToString());排序newdatas = datas.Order(myOrder);


(这里是文档结束)

http://www.dtcms.com/a/270302.html

相关文章:

  • ACE-Step:AI音乐生成基础模型
  • 代码详细注释:基于log.h的自定义日志库实现
  • 探索下一代云存储技术:对象存储、文件存储与块存储的区别与选择
  • Splunk练习 Boss of the SOC V1
  • 短视频矩阵系统的崛起:批量发布功能与多平台矩阵的未来
  • LeetCode 21. 合并两个有序链表
  • C#Halcon从零开发_Day18_OCR识别
  • 4. isaac sim4.2 教程-Core API-Hello robot
  • 【计算机组成原理】-CPU章节学习篇—笔记随笔
  • Linux 第一个系统程序 - 进度条
  • (C++)list列表相关基础用法(C++教程)(STL库基础教程)
  • 跨越NLP的三重曲线:从词法到叙事的进化之路
  • 使用python的 FastApi框架开发图书管理系统-前后端分离项目分享
  • huggingface笔记:文本生成Text generation
  • EXCEL(带图)转html
  • 基于LiteOS与SLE的多任务无线控制器项目实战
  • 深圳凭物联网软件开发构建智慧‘城市大脑‘
  • 什么是 3D 文件?
  • UE material advance 学习笔记
  • 【时时三省】(C语言基础)怎样引用指针变量
  • 免安装图片修改软件,一键批量处理
  • 16018.UE4+Airsim仿真环境搭建
  • 详细页智能解析算法:洞悉海量页面数据的核心技术
  • 软件系统测试的基本流程
  • 【PyTorch项目实战】VisRAG:基于视觉的多模态文档检索增强生成(文本+图像)
  • Android 事件分发机制深度解析
  • Android 中的多线程编程全面解析
  • YOLO融合[ICLR2025]PolaFormer中的极性感知线性注意力
  • docker proxy
  • C 解压文件