通过继承系统的ComboBox,写一个新控件ComboBoxEx,重写它的焦点以及文本更新事件,就可以轻松实现拼音首字母检索了。例如:输入 gd ,就可以出现“广东”。

1 using System;   
 2 using System.Collections.Generic;    
 3 using System.Text;    
 4 using System.Windows.Forms;    
 5 using System.Collections;    
 6    
 7 namespace PrintDoc    
 8 {    
 9    public class ComboBoxEx : ComboBox    
10    {    
11        private ArrayList m_list = new ArrayList();    
12    
13        protected override void OnEnter(EventArgs e)    
14        {    
15            m_list.Clear();    
16            m_list.AddRange(this.Items);    
17            base.OnEnter(e);    
18        }    
19    
20        protected override void OnLeave(EventArgs e)    
21        {    
22            this.Items.Clear();    
23            this.Items.AddRange(m_list.ToArray());    
24            base.OnLeave(e);    
25        }    
26    
27        protected override void OnTextUpdate(EventArgs e)    
28        {    
29            while (this.Items.Count > 0)    
30            {    
31                this.Items.RemoveAt(0);    
32            }    
33            foreach (object o in this.m_list)    
34            {    
35                if ( GetChineseSpell(o.ToString()).ToLower().Contains(this.Text.ToLower()))    
36                {    
37                    this.Items.Add(o);    
38                }    
39            }    
40            this.DroppedDown = true;    
41            this.Cursor = Cursors.Default;    
42            base.OnTextUpdate(e);    
43        }    
44    
45        static public string GetChineseSpell(string strText)    
46        {    
47            int len = strText.Length;    
48            string myStr = "";    
49            for (int i = 0; i < len; i++)    
50            {    
51                myStr += getSpell(strText.Substring(i, 1));    
52            }    
53            return myStr;    
54        }    
55    
56        static public string getSpell(string cnChar)    
57        {    
58            byte[] arrCN = Encoding.Default.GetBytes(cnChar);    
59            if (arrCN.Length > 1)    
60            {    
61                int area = (short)arrCN[0];    
62                int pos = (short)arrCN[1];    
63                int code = (area << 8) + pos;    
64                int[] areacode = { 45217, 45253, 45761, 46318, 46826, 47010, 47297, 47614, 48119, 48119, 49062, 49324, 49896, 50371, 50614, 50622, 50906,   51387, 51446, 52218, 52698, 52698, 52698, 52980, 53689, 54481 };    
65                for (int i = 0; i < 26; i++)    
66                {    
67                    int max = 55290;    
68                    if (i != 25) max = areacode[i + 1];    
69                    if (areacode[i] <= code && code < max)    
70                    {    
71                        return Encoding.Default.GetString(new byte[] { (byte)(65 + i) });    
72                    }    
73                }    
74                return "*";    
75            }    
76            else     
77                return cnChar;    
78        }    
79    }    
80 }    
81

用来进行语法转化的工具:http://codeconverter.sharpdevelop.net/SnippetConverter.aspx

转化之后的VB.NET版本如下。

1    Public Shared Function getHzPy()Function getHzPy(ByVal cnChar As String) As String   
 2        Dim arrCN As Byte() = System.Text.Encoding.[Default].GetBytes(cnChar)    
 3        If arrCN.Length > 1 Then    
 4            Dim area As Integer = CShort(arrCN(0))    
 5            Dim pos As Integer = CShort(arrCN(1))    
 6            Dim code As Integer = (area << 8) + pos    
 7            Dim areacode As Integer() = {45217, 45253, 45761, 46318, 46826, 47010, _    
 8             47297, 47614, 48119, 48119, 49062, 49324, _    
 9             49896, 50371, 50614, 50622, 50906, 51387, _    
10             51446, 52218, 52698, 52698, 52698, 52980, _    
11             53689, 54481}    
12            For i As Integer = 0 To 25    
13                Dim max As Integer = 55290    
14                If i <> 25 Then    
15                    max = areacode(i + 1)    
16                End If    
17                If areacode(i) <= code AndAlso code < max Then    
18                    Return System.Text.Encoding.[Default].GetString(New Byte() {CByte((65 + i))})    
19                End If    
20            Next    
21            Return "*"    
22        Else    
23            Return cnChar    
24        End If    
25    End Function

另外还有一篇相关的文章,除了计算拼音的算法不对之外,其他方面的事件考虑的比较周全。可以用上面的算法替换掉下面文章中的getHzPy方法。

(VB.NET)

除此之外,再贴两篇和AucoCompleteComboBox相关的文章,看似很好很强大。

http://www.codeproject.com/KB/architecture/MultiColumnFlatCombo.aspx (C++, English)

http://www.codeproject.com/KB/combobox/akautocomplete.aspx (VB.NET , English)


  汉字转拼音缩写的函数(C#)