带搜索的combobox就是给combobox一个依赖属性的itemsource,然后通过数据源中是否包含要查询的值,重新给combobox绑定数据源。
public class editcombobox : combobox
{
private bool t = true ; //首次获取焦点标志位
private observablecollection< object > bindinglist = new observablecollection< object >(); //数据源绑定list
private string edittext = "" ; //编辑文本内容
/// <summary>
/// 注册依赖事件
/// </summary>
public static readonly dependencyproperty itemssourcepropertynew = dependencyproperty.register( "myitemssource" , typeof (ienumerable), typeof (editcombobox), new frameworkpropertymetadata( new propertychangedcallback(valuechanged)));
/// <summary>
/// 数据源改变,添加数据源到绑定数据源
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
private static void valuechanged(dependencyobject d, dependencypropertychangedeventargs e)
{
editcombobox ecb = d as editcombobox;
ecb.bindinglist.clear();
//遍历循环操作
foreach (var item in ecb.myitemssource)
{
ecb.bindinglist.add(item);
}
}
/// <summary>
/// 设置或获取combobox的数据源
/// </summary>
public ienumerable myitemssource
{
get
{
return (ienumerable)getvalue(itemssourcepropertynew);
}
set
{
if (value == null )
clearvalue(itemssourcepropertynew);
else
setvalue(itemssourcepropertynew, value);
}
}
/// <summary>
/// 重写初始化
/// </summary>
/// <param name="e"></param>
protected override void oninitialized(eventargs e)
{
base .oninitialized(e);
this .iseditable = true ;
this .istextsearchenabled = false ;
this .itemssource = bindinglist;
}
/// <summary>
/// 下拉框获取焦点,首次搜索文本编辑框
/// </summary>
/// <param name="e"></param>
protected override void ongotfocus(routedeventargs e)
{
if (t)
findtextbox( this );
else
t = false ;
}
/// <summary>
/// 搜索编辑文本框,添加文本改变事件
/// </summary>
/// <param name="obj"></param>
private void findtextbox(dependencyobject obj)
{
for ( int i = 0; i < visualtreehelper.getchildrencount(obj); i++)
{
dependencyobject child = visualtreehelper.getchild(obj, i);
if (child!= null && child is textbox)
{
//注册文本改变事件
(child as textbox).textchanged += editcombobox_textchanged;
}
else
{
findtextbox(child);
}
}
}
/// <summary>
/// 文本改变,动态控制下拉条数据源
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void editcombobox_textchanged( object sender, textchangedeventargs e)
{
textbox tb = sender as textbox;
if (tb.isfocused)
{
this .isdropdownopen = true ;
if (edittext == this .text)
return ;
edittext = this .text;
setlist(edittext);
}
}
/// <summary>
/// 组合框关闭,数据源恢复
/// </summary>
/// <param name="e"></param>
protected override void ondropdownclosed(eventargs e)
{
base .ondropdownclosed(e);
if (myitemssource == null )
return ;
foreach (var item in myitemssource)
{
if (!bindinglist.contains(item))
bindinglist.add(item);
}
}
/// <summary>
/// 过滤符合条件的数据项,添加到数据源项中
/// </summary>
/// <param name="txt"></param>
private void setlist( string txt)
{
try
{
string temp1 = "" ;
string temp2 = "" ;
if (myitemssource == null )
return ;
foreach (var item in myitemssource)
{
temp1 = item.gettype().getproperty( this .displaymemberpath).getvalue(item, null ).tostring();
if ( string .isnullorempty( this .selectedvaluepath))
{
temp2 = "" ;
}
else
{
temp2 = item.gettype().getproperty( this .selectedvaluepath).getvalue(item, null ).tostring();
}
if (temp1.contains(txt)||temp2.startswith(txt))
{
if (!bindinglist.contains(item))
bindinglist.add(item);
}
else if (bindinglist.contains(item))
{
bindinglist.remove(item);
}
}
}
catch (exception ex)
{
messagebox.show(ex.tostring());
}
}
}
调用方法就是将数据源绑定到myitemssource上,剩下的就和原有的combobox用法一样了。
复制代码 代码如下:
<local:editcombobox myitemssource="{binding prolist,mode=twoway}" selecteditem="{binding selpro,mode=twoway}" selectedvaluepath="id" displaymemberpath="name"/>
效果演示
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
dy("nrwz");
查看更多关于C#实现带搜索功能的ComboBox的详细内容...