silverlight4/5 修改源码实现 DataGrid 中文按拼音排序(第二版)
先前已经实现的方法需要修改多个dll:
排序:System.Windows.Data.dll
DataGrid:System.Windows.Controls.Data.dll
DataForm:System.Windows.Controls.Data.DataForm.Toolkit.dll
问题在于System.Windows.Data.dll经常被其它SDK引用,这样就需要修改强签名,今天有时间看了看排序的代码,问题出现在这里:
System.Windows.Data\PagedCollectionView\PagedCollectionView.cs
public CultureSensitiveComparer(CultureInfo culture) : base() { this._culture = culture ?? CultureInfo.InvariantCulture; }
CultureInfo 用于本地化,如本地化的日期时间显示方式,当然也包含了排序方法。
提供有关特定区域性的信息。 这些信息包括区域性的名称、书写系统、使用的日历、用于数字和日期的格式以及排序字符串的顺序。
如果 culture 为空,则设置为 CultureInfo.InvariantCulture:
获取不依赖于区域性(固定)的 CultureInfo。
也就是说如果没有设置CultureInfo,就去掉区域设置。查看DataGird源码,哈哈,果然没有设置CultureInfo。
着手解决,CultureInfo.CurrentCulture:
获取表示当前线程使用的区域性的 CultureInfo 对象。
也就是如果 culture 为空,写为:
this._culture = culture ?? CultureInfo.CurrentCulture;
不就结了,不明白微软那样做出于什么考虑。
由于直接修改,排序:System.Windows.Data.dll,会引起强签名的麻烦,DataGrid看起来还没有其它SDK直接引用,从DataGrid入手,初始化排序类时设置CultureInfo就是了:
System.Windows.Controls.Data\DataGrid\DataGridDataConnection.cs
public object GetDataItem(int index) { Debug.Assert(index >= 0); IList list = this.List; if (list != null) { return (index < list.Count) ? list[index] : null; } PagedCollectionView collectionView = this.DataSource as PagedCollectionView; if (collectionView != null) { collectionView.Culture = collectionView.Culture ?? System.Globalization.CultureInfo.CurrentCulture; return (index < collectionView.Count) ? collectionView.GetItemAt(index) : null; }
这就是我加入的设置CultureInfo的代码:
collectionView.Culture = collectionView.Culture ?? System.Globalization.CultureInfo.CurrentCulture;
如果collectionView.Culture为空,设置为当前区域而不是去除区域。
测试通过。
这是 Silverlight 4 的版本, Silverlight 5 没有提供源代码,需要从汇编修改,从汇编代码来看,public object GetDataItem(int index)方法,Silverlight 4/5实现的代码一致。修改方法同上篇文章,不再叙述。
已修改好的DLL下载: