软件编程
位置:首页>> 软件编程>> C#编程>> C#实现带搜索功能的ComboBox

C#实现带搜索功能的ComboBox

作者:眾尋  发布时间:2022-08-29 06:52:48 

标签:C#,搜索,ComboBox

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com