您的位置:首页 > 其它

silverlight4/5 修改源码实现 DataGrid 中文按拼音排序

2013-08-29 16:42 393 查看
silverlight3的DataGrid中文按拼音排序,silverlight4/5不是,本文通过修改SDK DLL实现silverlight3的拼音排序。

老项目还是silverlight3的,升级silverlight4后,DataGrid不按拼音排序,用户意见很大,只得着手解决。网上常见解决方案是捕捉点击事件,自定义排序,我也照葫芦画瓢实现了,但用到DataGrid地方都要修改,以后用到DataGrid都要带个小尾巴,着实不便。继续问Google,发现国外论坛一片骂声,silverlight5没提供源代码,也就是说...天可怜见,DataGrid有源代码,silverlight3/4都有源代码,但silverlight5没有,能升级到4也可以。

源码位于:Program Files (x86)\Microsoft SDKs\Silverlight\v3.0\Toolkit\Jul09\Source\Source code.zip

DataGrid在System.Windows.Controls.Data项目中,将该项目加入到我的项目解决方案中,调试得出排序实现在System.Windows.Data.dll,打开System.Windows.Data项目,最终找到排序实现位于PagedCollectionView.cs:private List<object> SortList(List<object> list)。

对比silverlight3、silverlight4代码,差别很简单,注释掉的seq =为silverlight4的代码,可见只是将comparer去到,ThenBy是多列排序,OrderBy是单列排序。调试通过,DataGrid拼音排序正常。

switch (sort.Direction)
{
case System.ComponentModel.ListSortDirection.Ascending:
if (orderedEnum != null)
{
// thenby
//seq = orderedEnum.ThenBy(item => InvokePath(item, propertyPath, propertyType), comparer);
seq = orderedEnum.ThenBy(item => InvokePath(item, propertyPath, propertyType));
}
else
{
// orderby
//seq = seq.OrderBy(item => InvokePath(item, propertyPath, propertyType), comparer);
seq = seq.OrderBy(item => InvokePath(item, propertyPath, propertyType));
}

break;
case System.ComponentModel.ListSortDirection.Descending:
if (orderedEnum != null)
{
// thenby
//seq = orderedEnum.ThenByDescending(item => InvokePath(item, propertyPath, propertyType), comparer);
seq = orderedEnum.ThenByDescending(item => InvokePath(item, propertyPath, propertyType));
}
else
{
// orderby
//seq = seq.OrderByDescending(item => InvokePath(item, propertyPath, propertyType), comparer);
seq = seq.OrderByDescending(item => InvokePath(item, propertyPath, propertyType));
}

break;
default:
break;
}


经查仅 System.Windows.Controls.Data.DataForm.Toolkit.dll 也依赖 System.Windows.Data.dll,同System.Windows.Controls.Data重新编译即可。我的解决办法是直接替换微软原始dll,多快好省。

没有升级到silverlight5毕竟不爽,接下来研究反编译,先反编译为C#代码,确认排序方式与silverlight4基本一致。反编译后的C#代码没法直接编译,问Google了解到使用ilasm反编译为IL汇编,vs2012的ilasm路径:

Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\

用ilasm打开System.Windows.Data.dll,转储为sort.IL文件,排序代码位于:


SortList(class [mscorlib]System.Collections.Generic.List`1<object> list) cil managed

{

}


用silverlight4的代码替换掉silverlight5。接下来用ilasm命令将IL重新编译为DLL,路径:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319

由于是强签名的,借用silverlight4源码中带的RiaClient.snk,编译命令:

ilasm d:\temp\5\sort.il /output=d:\temp\5\System.Windows.Data.dll /dll /RESOURCE=d:\temp\5\sort.res /key=d:\temp\5\RiaClient.snk

使用.Net Reflector查看System.Windows.Data.dll的PublicKeyToken:


// Assembly System.Windows.Data, Version 5.0.5.0

Location: D:\Temp\5\System.Windows.Data.dll
Name: System.Windows.Data, Version=5.0.5.0, Culture=neutral, PublicKeyToken=1dd0be75816bbb62
Type: Library


接下来反编译DataGrid所在的System.Windows.Controls.Data.dll为dg.IL文件,修改依赖System.Windows.Data.dll的PublicKeyToken:


.assembly extern System.Windows.Data
{
.publickeytoken = (31 BF 38 56 AD 36 4E 35 ) // 1.8V.6N5
.ver 5:0:5:0
}


使用1dd0be75816bbb62,替换掉31 BF 38 56 AD 36 4E 35:


.assembly extern System.Windows.Data
{
.publickeytoken = (1D D0 BE 75 81 6B BB 62 ) // 1.8V.6N5
.ver 5:0:5:0
}


重新编译为dll,命令:

ilasm d:\temp\5\dg.il /output=d:\temp\5\System.Windows.Controls.Data.dll /dll/RESOURCE=d:\temp\5\dg.res /key=d:\temp\5\RiaClient.snk

System.Windows.Controls.Data.DataForm.Toolkit.dll 也同 System.Windows.Controls.Data.dll 一样处理。替换掉微软原始的dll,测试通过。

已修改好的DLL下载:

DataGrid_SDK
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: