我使用了一个treeview组件来实现我的html编辑器。 我使用子节点用数据时间字符串记录历史事件,包括A.C.和B.C.时间。我测试过的树视图的子节点示例如下所示。
-History
﹂ 0123/05/05 B.C. event001
﹂ 2015/01/01 A.D. event002
﹂ 2017/01/21 A.D. event003
﹂ 2125/12/05 B.C. event000
排序后的正确结果应如下所示
-History
﹂ 2125/12/05 B.C. event000
﹂ 0123/05/05 B.C. event001
﹂ 2015/01/01 A.D. event002
﹂ 2017/01/21 A.D. event003
我使用的代码只是simillar到以下帖子: Sorting child nodes of a treeview after populating the treeview in c# winforms
using System.Collections;
using System.Windows.Forms;
namespace TreeViewEditor
{
public class NodeSorter : IComparer
{
public int Compare(object x, object y)
{
TreeNode tx = x as TreeNode;
TreeNode ty = y as TreeNode;
return string.Compare(tx.Text, ty.Text);
}
}
}
当子节点仅包含A.D.日期时间字符串时,它可以正常工作。我想知道当子节点同时包含A.D.和B.C.时如何正确排序。树视图中的日期时间字符串。
答案 0 :(得分:1)
执行此操作的一种方法是使用类来表示日期,并在类上实现IComparable
。这允许您自定义排序算法,以便B.C.日期按相反顺序排序(与A.D.日期相比)。
下面我创建了一个具有年,月,日属性的类,以及为B.C.设置为false
的bool。日期。我添加了一个Parse()
方法,可以使用您的一个示例字符串(没有“event”部分)并返回一个BCADDate
对象。如果需要,添加“事件”属性以及从字符串中解析事件的能力将是微不足道的(下面的注释我可以添加它)。
基本上比较的工作方式如下:
-1
0
修改强>
我还添加了IComparer
接口的实现,以防有助于在树视图中使用它。
以下是代码:
class BCADDate : IComparable, IComparer
{
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public bool IsAD { get; set; }
public static BCADDate Parse(string input)
{
var result = new BCADDate();
if (string.IsNullOrWhiteSpace(input))
throw new ArgumentException("input cannot be null, empty, or whitespace");
var dateADParts = input.Split(' ');
var dateParts = dateADParts[0].Split('/');
if (dateParts.Length < 3)
throw new FormatException(
"The string must have three parts separated by the '/' character.");
try
{
result.Year = int.Parse(dateParts[0]);
result.Month = int.Parse(dateParts[1]);
result.Day = int.Parse(dateParts[2]);
}
catch
{
throw new FormatException(
"All parts of the date portion must be valid integers.");
}
result.IsAD = (dateADParts.Length == 1)
? true // A.D. is true if nothing is specified
: dateADParts[1].IndexOf("A", StringComparison.OrdinalIgnoreCase) > -1;
return result;
}
public int CompareTo(object obj)
{
var other = obj as BCADDate;
if (other == null) return 1;
var BCMultiplier = IsAD ? 1 : -1;
// Use default comparers for our fields
if (this.IsAD != other.IsAD)
return this.IsAD.CompareTo(other.IsAD);
if (this.Year != other.Year)
return this.Year.CompareTo(other.Year) * BCMultiplier;
if (this.Month != other.Month)
return this.Month.CompareTo(other.Month) * BCMultiplier;
if (this.Day != other.Day)
return this.Day.CompareTo(other.Day) * BCMultiplier;
return 0;
}
public int Compare(object x, object y)
{
var first = x as BCADDate;
var second = y as BCADDate;
if (first == null) return second == null ? 0 : -1;
return first.CompareTo(second);
}
public override string ToString()
{
var bcad = IsAD ? "A.D." : "B.C.";
return $"{Year:0000}/{Month:00}/{Day:00} {bcad}";
}
}
以下是用法示例:
var dates = new List<BCADDate>
{
BCADDate.Parse("0123/05/05 B.C."),
BCADDate.Parse("2015/01/01 A.D."),
BCADDate.Parse("2017/01/21 A.D."),
BCADDate.Parse("2125/12/05 B.C.")
};
Console.WriteLine("Original ordering:");
dates.ForEach(Console.WriteLine);
dates.Sort();
Console.WriteLine("------------------");
Console.WriteLine("Sorted ordering:");
dates.ForEach(Console.WriteLine);
Console.Write("\nDone!\nPress any key to exit...");
Console.ReadKey();
<强>输出强>
答案 1 :(得分:0)
基于Rufus L的解决方案,我在TreeView组件中实现了这个排序功能。令人惊讶的是,我只是对TreeView的NodeSorter进行了一些小修改。 Rufus L的解决方案在我的treeview应用程序中运行得很好。
修改后的源代码如下所示:
using System;
using System.Collections;
using System.Windows.Forms;
namespace TreeViewEditor
{
class BCADDate : IComparable
{
public int Year { get; set; }
public int Month { get; set; }
public int Day { get; set; }
public bool IsAD { get; set; }
public static BCADDate Parse(string input)
{
var result = new BCADDate();
if (string.IsNullOrWhiteSpace(input))
throw new ArgumentException("input cannot be null, empty, or whitespace");
var dateADParts = input.Split(' ');
var dateParts = dateADParts[0].Split('/');
if (dateParts.Length < 3)
throw new FormatException(
"The string must have three parts separated by the '/' character.");
try
{
result.Year = int.Parse(dateParts[0]);
result.Month = int.Parse(dateParts[1]);
result.Day = int.Parse(dateParts[2]);
}
catch
{
throw new FormatException(
"All parts of the date portion must be valid integers.");
}
result.IsAD = (dateADParts.Length == 1)
? true // A.D. is true if nothing is specified
: dateADParts[1].IndexOf("A", StringComparison.OrdinalIgnoreCase) > -1;
return result;
}
public int CompareTo(object obj)
{
var other = obj as BCADDate;
if (other == null) return 1;
var BCMultiplier = IsAD ? 1 : -1;
// Use default comparers for our fields
if (this.IsAD != other.IsAD)
return this.IsAD.CompareTo(other.IsAD);
if (this.Year != other.Year)
return this.Year.CompareTo(other.Year) * BCMultiplier;
if (this.Month != other.Month)
return this.Month.CompareTo(other.Month) * BCMultiplier;
if (this.Day != other.Day)
return this.Day.CompareTo(other.Day) * BCMultiplier;
return 0;
}
}
public class NodeSorter : IComparer
{
public int Compare(object x, object y)
{
TreeNode tx = x as TreeNode;
TreeNode ty = y as TreeNode;
BCADDate a = BCADDate.Parse(tx.Text);
BCADDate b = BCADDate.Parse(ty.Text);
return a.CompareTo(b);
}
}
}
我的申请中使用的代码如下所示:
TreeView2.TreeViewNodeSorter = new NodeSorter();