WinForm TextBox水印+ListBox实现模糊和拼音匹配

因项目需要,做一个搜索框功能,使用TextBox+ListBox实现,效果图:

难点不大,就把其中几个重要的点写一下:

1.实现TextBox水印:

 public partial class WaterTextBox : System.Windows.Forms.TextBox
    {
        #region 字段、属性
        /// <summary>
        /// 水印文字
        /// </summary>
        private string m_WatermarkText;
        /// <summary>
        /// 水印消息定义
        /// </summary>
        private const int WT_Mark = 0x1501;

        [Description("水印文字")]
        public string WatermarkText
        {
            get { return m_WatermarkText; }
            set
            {
                m_WatermarkText = value;
                SetWatermark(m_WatermarkText);
            }
        }
        #endregion

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, uint wParam, [MarshalAs(UnmanagedType.LPWStr)] string lParam);

        public WaterTextBox()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 设置水印文字
        /// </summary>
        /// <param name="watermarkText"></param>
        private void SetWatermark(string watermarkText)
        {
            SendMessage(this.Handle, WT_Mark, 0, watermarkText);
        }
    }

2.拼音匹配

        /// <summary>
        /// 拼音检索
        /// </summary>
        /// <param name="strText"></param>
        /// <returns></returns>
        public string GetChineseSpell(string strText)
        {
            int len = strText.Length;
            string myStr = "";
            for (int i = 0; i < len; i++)
            {
                myStr += getSpell(strText.Substring(i, 1));
            }
            return myStr;
        }

        /// <summary>
        /// 得到首字母
        /// </summary>
        /// <param name="cnChar"></param>
        /// <returns></returns>
        public string getSpell(string cnChar)
        {
            byte[] arrCN = Encoding.Default.GetBytes(cnChar);
            if (arrCN.Length > 1)
            {
                int area = (short)arrCN[0];
                int pos = (short)arrCN[1];
                int code = (area << 8) + pos;
                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 };
                for (int i = 0; i < 26; i++)
                {
                    int max = 55290;
                    if (i != 25) max = areacode[i + 1];
                    if (areacode[i] <= code && code < max)
                    {
                        return Encoding.Default.GetString(new byte[] { (byte)(65 + i) });
                    }
                }
                return "";
            }
            else
                return cnChar;
        }
这两个方法来自:http://www.codeweblog.com/%E5%AE%9E%E7%8E%B0textbox-listboxcontrol%E6%8B%BC%E9%9F%B3%E6%A3%80%E7%B4%A2-c/

3.想程序更通用一点,所以绑定的值想交给外边设置,通过反射的方式来进行读取

        /// <summary>
        /// ListBox数据源
        /// </summary>
        private object m_DataSource;
        private string m_LBDisplayMember;
        private string m_LBValueMember;

        /// <summary>
        /// ListBox显示值
        /// </summary>
        public string LBDisplayMember
        {
            get
            {
                return m_LBDisplayMember;
            }

            set
            {
                m_LBDisplayMember = value;
            }
        }

        /// <summary>
        /// ListBox值
        /// </summary>
        public string LBValueMember
        {
            get
            {
                return m_LBValueMember;
            }

            set
            {
                m_LBValueMember = value;
            }
        }     
           
            /// <summary>
        /// 绑定ListBox数据
        /// </summary>
        /// <param name="dataSource"></param>
        /// <param name="displayMember"></param>
        /// <param name="valueMember"></param>
        public void BindListBoxData(Object dataSource, string displayMember, string valueMember)
        {
            this.m_DataSource = dataSource;
            this.m_LBDisplayMember = displayMember;
            this.m_LBValueMember = valueMember;
        }

     private void txt_Search_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrWhiteSpace(txt_Search.Text))
            {
                lb_Data.Visible = false;
            }
            else
            {
                lb_Data.Visible = true;
                SetListBoxItem(txt_Search.Text);
            }
        }

      /// <summary>
      /// 设置ListBox内容
      /// </summary>
      /// <param name="text">输入文本</param>

private void SetListBoxItem(string text)
        {
            if (m_DataSource != null)
            {
                List<ObjectSource> dataSource = new List<ObjectSource>();
                Type t = m_DataSource.GetType();
                if (t.IsGenericType)
                {
                    int count = Convert.ToInt32(t.GetProperty("Count").GetValue(m_DataSource, null));
                    for (int i = 0; i < count; i++)
                    {
                        object listItem = t.GetProperty("Item").GetValue(m_DataSource, new object[] { i });
                        Type item = listItem.GetType();
                        string value = item.GetProperty(this.m_LBDisplayMember).GetValue(listItem) as string;
                        if (value.Contains(text) || GetChineseSpell(value).ToLower().Contains(text.ToLower()))
                        {
                            dataSource.Add(new ObjectSource()
                            {
                                ElementId = item.GetProperty(this.m_LBValueMember).GetValue(listItem),
                                Name = item.GetProperty(this.m_LBDisplayMember).GetValue(listItem),
                            });
                        }
                    }
                }
                BindListBoxData(dataSource);
            }
        }

        private void BindListBoxData(List<ObjectSource> dataSource)
        {
            this.lb_Data.DataSource = dataSource;
            this.lb_Data.DisplayMember = this.m_LBDisplayMember;
            this.lb_Data.ValueMember = this.m_LBValueMember;
        }

 

附上源码:https://files.cnblogs.com/files/hualuohuakaihuamanyuan/SearchTextBox.rar

 

posted @ 2017-08-10 10:26  花落花开花满园  阅读(977)  评论(1编辑  收藏  举报