因项目需要,做一个搜索框功能,使用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