支持拼音首字母查詢的ComboBox


功能:輸入字母,自動篩選Items中對應拼音首字母的項目,如:bk,篩選“博客”,“邊框”等。另外支持英文字母開頭項目,支持自定義項目顏色。

 

拼音方案直接引用微軟自家的類庫,詳見:http://www.microsoft.com/zh-cn/download/details.aspx?id=15251

類庫支持獲取簡體中文字符的常用屬性比如拼音,多音字,同音字,筆畫數。

請下載並在項目中引用ChnCharInfo.dll

 

View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.ComponentModel;
using System.Collections;
using Microsoft.International.Converters.PinYinConverter;
using System.Windows.Forms;
using System.Drawing;

namespace CustomControlLibrary
{
    public class ComboBoxEx : System.Windows.Forms.ComboBox
    {
        /// <summary>
        /// 解決ComboBox的一個Bug,詳見:
        /// https://connect.microsoft.com/VisualStudio/feedback/details/721868/combobox-throws-argumentoutofrangeexception-after-clearing-while-in-droppeddown-state
        /// </summary>
        public override int SelectedIndex
        {
            get
            {
                if (Items.Count > 0)
                    return base.SelectedIndex;
                else
                    return -1;
            }
            set
            {
                if (Items.Count > 0)
                {
                    base.SelectedIndex = value;
                }
            }
        }

        public ComboBoxEx()
        {
            Enter += new System.EventHandler(ComboBoxEx_Enter);
            Leave += new System.EventHandler(ComboBoxEx_Leave);
            TextUpdate += new System.EventHandler(ComboBoxEx_TextUpdate);

            DrawMode = DrawMode.OwnerDrawVariable;
            DrawItem += new DrawItemEventHandler(ComboBoxEx_DrawItem);
        }

        #region 自定義繪制每項的顏色
        private void ComboBoxEx_DrawItem(object sender, DrawItemEventArgs e)
        {
            ComboBox cb = (ComboBox)sender;
            if (e.Index != -1)
            {
                cb.DrawMode = DrawMode.OwnerDrawVariable;
                // Draw the background of the ListBox control for each item.
                e.DrawBackground();
                // Define the default color of the brush as black.
                Brush myBrush = Brushes.Black;

                // Determine the color of the brush to draw each item based on the index of the item to draw.
                //if (e.Index % 2 == 0)
                //{
                //    myBrush = Brushes.DarkSlateGray;
                //}
                // Draw background color for each item.
                //e.Graphics.FillRectangle(myBrush, e.Bounds);

                // Draw the current item text based on the current Font and the custom brush settings.
                e.Graphics.DrawString(cb.Items[e.Index].ToString(), e.Font, myBrush, e.Bounds, StringFormat.GenericDefault);
                // If the ListBox has focus, draw a focus rectangle around the selected item.
                e.DrawFocusRectangle();
            }
        }
        #endregion

        #region 支持拼音首字母查詢

        private ArrayList lstItems = new ArrayList();

        /// <summary>
        /// 漢字轉拼音首字母
        /// </summary>
        /// <param name="scrChar"></param>
        /// <returns></returns>
        public List<string> Chinese2Pinyin(char scrChar)
        {
            try
            {
                ChineseChar cnChar = new ChineseChar(scrChar);
                List<string> lstStr = new List<string>(cnChar.PinyinCount);
                for (int i = 0; i < cnChar.PinyinCount; i++)
                {
                    lstStr.Add(cnChar.Pinyins[i]);
                }
                return lstStr;
            }
            catch
            {
                return new List<string> { scrChar.ToString() };
            }
        }

        private void ComboBoxEx_Enter(object sender, EventArgs e)
        {
            ComboBox cb = (ComboBox)sender;
            lstItems.Clear();
            lstItems.AddRange(cb.Items);
        }

        private void ComboBoxEx_Leave(object sender, EventArgs e)
        {
            ComboBox cb = (ComboBox)sender;
            object obj = null;

            if (cb.Items.Count != 0)
                obj = cb.SelectedItem;

            cb.DataSource = null;
            cb.Items.Clear();
            //cb.Items.AddRange(this.lstTeam.ToArray());
            cb.DataSource = (ArrayList)lstItems.Clone();
            cb.SelectedItem = obj;
        }

        private void ComboBoxEx_TextUpdate(object sender, EventArgs e)
        {
            try
            {
                ComboBox cb = (ComboBox)sender;
                cb.DataSource = null;

                if (cb.Items.Count == 0)
                {
                    cb.SelectedIndex = -1;
                    cb.SelectedItem = null;
                }

                if (string.IsNullOrWhiteSpace(cb.Text))
                {
                    cb.Items.Clear();
                    cb.Items.AddRange(lstItems.ToArray());
                }
                else
                {
                    ArrayList lstCurItems = new ArrayList();

                    int count = cb.Text.Length - 1;
                    if (0 == count)
                        lstCurItems = lstItems;
                    else
                        lstCurItems.AddRange(cb.Items);

                    cb.Items.Clear();
                    foreach (object obj in lstCurItems)
                    {
                        if (count < obj.ToString().Length)
                        {
                            foreach (string item in Chinese2Pinyin(obj.ToString()[count]))
                            {
                                if (item.ToLower()[0] == cb.Text.ToLower()[count])
                                {
                                    cb.Items.Add(obj);
                                    break;
                                }
                            }
                        }
                    }
                }
                if (cb.Items.Count == 0)
                {
                    cb.SelectedIndex = -1;
                    cb.SelectedItem = null;
                    cb.Text = null;
                }
                cb.SelectionStart = cb.Text.Length;
                cb.DropDownHeight = 140;
                cb.DroppedDown = true;
                cb.Cursor = Cursors.Default;
            }
            catch (Exception)
            {
                throw;
            }
        } 

        #endregion
    }
}

 

P.S.

純經驗記錄,方便大家!代碼沒技術含量,還有可改進的地方。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM