DataView.Sort - 不仅仅是asc/desc(需要自定义排序)
我有一个从数据集构建的报告。该数据集使用Sort属性对数据进行排序。我知道我可以创造一种表达这样的:DataView.Sort - 不仅仅是asc/desc(需要自定义排序)
“场递减,场2 ASC”
但我现在需要的是一种方法做一个自定义排序。在SQL中,我可以做这样的事情进行自定义排序:
order by
case when field = 'Some Value' then 0 end
case when field = 'Another Value' then 1 end
从根本上重新定义我的排序(即,一些价值来之前的另一值)。
是否有可能对DataView做类似的表达式?
好吧,我刚刚刮起这件事真正的快,并没有完成所有的neccessary错误处理和零检查,但它应该给你一个想法,应该是enou GH让你开始:
public static class DataTableExtensions
{
public static DataView ApplySort(this DataTable table, Comparison<DataRow> comparison)
{
DataTable clone = table.Clone();
List<DataRow> rows = new List<DataRow>();
foreach (DataRow row in table.Rows)
{
rows.Add(row);
}
rows.Sort(comparison);
foreach (DataRow row in rows)
{
clone.Rows.Add(row.ItemArray);
}
return clone.DefaultView;
}
}
用法:
DataTable table = new DataTable();
table.Columns.Add("IntValue", typeof(int));
table.Columns.Add("StringValue");
table.Rows.Add(11, "Eleven");
table.Rows.Add(14, "Fourteen");
table.Rows.Add(10, "Ten");
table.Rows.Add(12, "Twelve");
table.Rows.Add(13, "Thirteen");
//排序的StringValue:
DataView sorted = table.ApplySort((r, r2) =>
{
return ((string)r["StringValue"]).CompareTo(((string)r2["StringValue"]));
});
结果:
11十一
14十四
10十
13十三
12十二
//排序INTVALUE:
DataView sorted = table.ApplySort((r, r2) =>
{
return ((int)r["IntValue"]).CompareTo(((int)r2["IntValue"]));
});
结果:
10十
11十一
13十三
12十二
14十四
编辑:它更改为扩展方法。
现在在你的Lambda中(或者你可以创建一个完整的比较方法),你可以做任何你需要的自定义排序逻辑。请记住,-1小于,0等于,1大于。
我不这么认为。但是你可以改变你的SQL返回一个“CustomSort”列,它是你的case语句的结果:
select
(case when f = 'a' then 0 else 1 end) as CustomSort
from MyTable
这是可能的解决方案;希望是我不必使用的,因为这意味着要编辑大约20多个报表的SQL。 – bugfixr 2009-02-24 16:18:20
你可以使用if或switch语句来获得类似的功能的选择case语句:
if (Something == "1")
MyView.Sort = "Field1 ASC";
else
MyView.Sort = "Field2 ASC";
OR
switch (MyProperty)
{
case 1:
MyView.Sort = "Field1 ASC";
break;
case 2:
MyView.Sort = "Field2 ASC";
break;
default:
MyView.Sort = "Field3 ASC";
break;
}
我喜欢BFree的答案,但我担心我的代码最终会更新克隆表而不是真正的表。通过将计算DataColumn
它((我没有经历过它认为足以知道这是实际上是一个问题,如果你只使用扩展方法在DataView
)
您可以在原来的DataTable
做到这一点使用Expression
属性),然后对其值进行排序。
在你的情况下,它会是这样的:
DataColumn c = myTable.Columns.Add("Sort", typeof(int));
c.Expression = "iif(field='SomeValue', 0, iif(field='AnotherValue', 1, 2))";
这种种SomeValue
第一,AnotherValue
秒,以及其他一切之后。
我知道这篇文章有点旧了,但是我通过实现IComparable来解决这个问题。在这个例子中,我想按版本进行排序(格式为0.0.0.0作为字符串)。
这里是版本控制类,它实现了IComparable:
public class Versioning : IComparable {
string _version;
int _major;
public int Major {
get { return (_major); }
set { _major = value; }
}
int _minor;
public int Minor {
get { return (_minor); }
set { _minor = value; }
}
int _beta;
public int Beta {
get { return (_beta); }
set { _beta = value; }
}
int _alpha;
public int Alpha {
get { return (_alpha); }
set { _alpha = value; }
}
public Versioning(string version) {
_version = version;
var splitVersion = SplitVersion();
if (splitVersion.Length < 4) {
Major = Minor = Beta = Alpha = 0;
}
if (!int.TryParse(splitVersion[0], out _major)) _major = 0;
if (!int.TryParse(splitVersion[1], out _minor)) _minor = 0;
if (!int.TryParse(splitVersion[2], out _beta)) _beta = 0;
if (!int.TryParse(splitVersion[3], out _alpha)) _alpha = 0;
}
string[] SplitVersion() {
return (_version.Split('.'));
}
int GetCompareTo(Versioning versioning) {
var greater = -1;
var equal = 0;
var less = 1;
if (Major > versioning.Major) return (greater);
if (Major < versioning.Major) return (less);
if (Minor > versioning.Minor) return (greater);
if (Minor < versioning.Minor) return (less);
if (Beta > versioning.Beta) return (greater);
if (Beta < versioning.Beta) return (less);
if (Alpha > versioning.Alpha) return (greater);
if (Alpha < versioning.Alpha) return (less);
return (equal);
}
public int CompareTo(Versioning versioning) {
return (GetCompareTo(versioning));
}
public override string ToString() {
return (_version);
}
public int CompareTo(object obj) {
if (obj == null) return (1);
return (GetCompareTo((Versioning)obj));
}
}
而当你添加此列,而不是把版本作为一个字符串表,添加它作为版本控制类:
_table.Columns.Add("Version", typeof(Versioning));
_view = new View(_table);
然后排序通常:
_view.Sort = "Version";
我欠你一杯啤酒。 – Orestes 2013-02-20 14:50:30
很好的回答。只需要对双向排序进行一些调整,然后将视图重新绑定到网格中。 – tys 2015-04-07 07:31:35