C#实现带搜索功能的ComboBox
程序员文章站
2023-12-31 21:51:04
带搜索的combobox就是给combobox一个依赖属性的itemsource,然后通过数据源中是否包含要查询的值,重新给combobox绑定数据源。
pu...
带搜索的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"/>
效果演示
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。