首页 > 编程 > C# > 正文

C#实现带搜索功能的ComboBox

2020-01-24 00:57:32
字体:
来源:转载
供稿:网友

带搜索的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"/>

效果演示

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表