silverlight4/5 修改 DataGrid 源码实现按拼音排序_.NET_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > .NET > silverlight4/5 修改 DataGrid 源码实现按拼音排序

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

 2013/8/29 18:01:40  tailss  博客园  我要评论(0)
  • 摘要:silverlight3的DataGrid中文按拼音排序,silverlight4/5不是,本文通过修改SDKDLL实现silverlight3的拼音排序。老项目还是silverlight3的,升级silverlight4后,DataGrid不按拼音排序,用户意见很大,只得着手解决。网上常见解决方案是捕捉点击事件,自定义排序,我也照葫芦画瓢实现了,但用到DataGrid地方都要修改,以后用到DataGrid都要带个小尾巴,着实不便。继续问Google,发现国外论坛一片骂声
  • 标签:Silverlight 实现 源码 tag Silverlight4

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.dll和System.Windows.Data.dll没有被其他强签名dll依赖,我的解决办法是直接替换微软原始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

 

替换掉微软原始的dll,测试通过。

 

已修改好的DLL下载:

DataGrid_SDK

 

发表评论
用户名: 匿名