在win8上构建按拼音排序的GridView控件
本人最近因为项目,用C#做了一个可以在win8上使用拼音排序的的GridView控件。其中该控件主要支持以下几个功能:
①支持拼音排序
②支持字母Item和内容Item区分样式
③支持点击字母Item缩放子内容Item
④方便地扩展到各种Model
具体效果如图1所示。接下去对这几个功能的实现进行详细介绍。
①支持拼音排序
②支持字母Item和内容Item区分样式
③支持点击字母Item缩放子内容Item
④方便地扩展到各种Model
具体效果如图1所示。接下去对这几个功能的实现进行详细介绍。
图1
1.排序的实现
win8中没有像wp中的AlphaKeyGroup<T>那样有现成的分类数据结构。所以,我自己写了一个SpellHelper的Class来专门获取一个字符串的首拼字母,如果是符号,则返回“#”。核心代码如下所示。在代码中,可以看到有一个
strChineseFirstPY字符串,它是一个汉字拼音首字母列表, 包含了20902个汉字的U icode 码。获取字符串第一个字符的Unicode与strChineseFirstPY中的字母做映射,从而,能够较快算出第一个拼音。该方法经过测试,处理50000个中文字符串,大概需要47秒左右,在应用中,基本可以满足我们的需求了。
SpellHelper.cs
从代码中可以看出,在 调用NotifyDataChanged方法时,主要完成了两步,第一步调用了buildGroupedList方法生成了一个ObservableCollection<GroupInfoList<object>>类型的数据结构,每个GroupInfoList<T>都有一个Key,即一个字母索引,内部包含了带有该索引的所有模型,也就是说该数据结构最多会有27个GroupInfoList<object>,即a~z和#;第2步,则生成了一个用于匹配到界面的ObservableCollection<object>集合,该集合内的模型与NotifyDataChanged方法输入的的模型集合不一样,它不仅包含了后者的集合,而且对其进行了分组分组排序,而且每组第一个是表示索引的模型。
SpellGroupedGridView.CS
win8中没有像wp中的AlphaKeyGroup<T>那样有现成的分类数据结构。所以,我自己写了一个SpellHelper的Class来专门获取一个字符串的首拼字母,如果是符号,则返回“#”。核心代码如下所示。在代码中,可以看到有一个
strChineseFirstPY字符串,它是一个汉字拼音首字母列表, 包含了20902个汉字的U icode 码。获取字符串第一个字符的Unicode与strChineseFirstPY中的字母做映射,从而,能够较快算出第一个拼音。该方法经过测试,处理50000个中文字符串,大概需要47秒左右,在应用中,基本可以满足我们的需求了。
SpellHelper.cs
public static string GetFirstPinyin(string strText,out bool isChar)
{
isChar = true;
if (strText == null || strText.Length == 0)
return strText;
string myStr = string.Empty;
char vChar = (strText.ToCharArray())[0];
// 若是字母则直接返回
if ((vChar >= 'a' && vChar <= 'z') || (vChar >= 'A' && vChar <= 'Z'))
myStr = vChar.ToString();
else if ((int)vChar >= 19968 && (int)vChar <= 40869)
{
// 对可以查找的汉字计算它的首拼音字母的位置,然后输出
myStr = strChineseFirstPY[(int)vChar - 19968].ToString();
isChar = false;
}
else {
myStr = "#";
}
return myStr;
}// 获取首字的形状拼音字母
有了以上的辅助类以后,就可以对目标无序集合进行分组了。为了能够达到分组的效果,首先要有一个能将无序模型集合转化成拼音分类排序集合的方法,在本例中,我继承了自GridView的SpellGroupedGridView,,它有名为NotifyDataChanged(ObservableCollection<T>,ModelDataHelper)的一个方法,暴露给用户设置模型数据集合用的。该方法第一个参数就是用户要输入的无序集合,第二个参数是一个模板抽象类,便于扩展,该参数将在后面几节进行介绍。NotifyDataChanged函数的代码如下。从代码中可以看出,在 调用NotifyDataChanged方法时,主要完成了两步,第一步调用了buildGroupedList方法生成了一个ObservableCollection<GroupInfoList<object>>类型的数据结构,每个GroupInfoList<T>都有一个Key,即一个字母索引,内部包含了带有该索引的所有模型,也就是说该数据结构最多会有27个GroupInfoList<object>,即a~z和#;第2步,则生成了一个用于匹配到界面的ObservableCollection<object>集合,该集合内的模型与NotifyDataChanged方法输入的的模型集合不一样,它不仅包含了后者的集合,而且对其进行了分组分组排序,而且每组第一个是表示索引的模型。
SpellGroupedGridView.CS
public void NotifyDataChanged<T>(object data,ModelDataHelper dataHelper)
{
DataHelper = dataHelper;
ObservableCollection<T> items = data as Obs