欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C#实现带搜索功能的ComboBox

程序员文章站 2022-03-26 08:37:37
带搜索的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"/>

效果演示

C#实现带搜索功能的ComboBox

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。