因项目需要,做一个搜索框功能,使用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; }
附上源码:http://files.cnblogs.com/files/hualuohuakaihuamanyuan/SearchTextBox.rar