【问题标题】:WPF Filter a ListBoxWPF 过滤列表框
【发布时间】:2022-03-17 02:14:12
【问题描述】:

我有一个绑定到字符串列表的ListBox。我想在TextBox 中输入文本时过滤列表。我该怎么做?

public void ListLoad()
{
    ElementList = new List<string>(); // creation a list of strings
    ElementList.Add("1"); // add a item of string
    ElementList.Add("2"); // add a item of string

    DataContext = this; // set the data context
}

我在 XAML 中绑定它:

ItemsSource="{Binding ElementList}"

【问题讨论】:

    标签: c# wpf list xaml listbox


    【解决方案1】:

    CollectionViewSource 类可以在这里提供帮助。据我所知,它具有许多过滤、排序和分组集合的功能。

    ICollectionView view = CollectionViewSource.GetDefaultView(ElementList);
    view.Filter = (o) => {return o;}//here is the lambda with your conditions to filter
    

    当您不需要任何过滤器时,只需将view.Filter 设置为null。 另请查看filtering上的这篇文章

    【讨论】:

      【解决方案2】:

      这是一个用于绑定过滤器的附加属性:

      using System;
      using System.Windows;
      using System.Windows.Controls;
      
      public static class Filter
      {
          public static readonly DependencyProperty ByProperty = DependencyProperty.RegisterAttached(
              "By",
              typeof(Predicate<object>),
              typeof(Filter),
              new PropertyMetadata(default(Predicate<object>), OnByChanged));
      
          public static void SetBy(ItemsControl element, Predicate<object> value)
          {
              element.SetValue(ByProperty, value);
          }
      
          public static Predicate<object> GetBy(ItemsControl element)
          {
              return (Predicate<object>)element.GetValue(ByProperty);
          }
      
          private static void OnByChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              if (d is ItemsControl itemsControl &&
                  itemsControl.Items.CanFilter)
              {
                  itemsControl.Items.Filter = (Predicate<object>)e.NewValue;
              }
          }
      }
      

      在 xaml 中这样使用:

      <DataGrid local:Filter.By="{Binding Filter}"
                ItemsSource="{Binding Foos}">
          ...
      

      和视图模型:

      public class ViewModel : INotifyPropertyChanged
      {
          private string filterText;
          private Predicate<object> filter;
      
          public event PropertyChangedEventHandler PropertyChanged;
      
          public ObservableCollection<Foo> Foos { get; } = new ObservableCollection<Foo>();
      
          public string FilterText
          {
              get { return this.filterText; }
              set
              {
                  if (value == this.filterText) return;
                  this.filterText = value;
                  this.OnPropertyChanged();
                  this.Filter = string.IsNullOrEmpty(this.filterText) ? (Predicate<object>)null : this.IsMatch;
              }
          }
      
          public Predicate<object> Filter
          {
              get { return this.filter; }
              private set
              {
                  this.filter = value;
                  this.OnPropertyChanged();
              }
          }
      
          protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
          {
              this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
          }
      
          private bool IsMatch(object item)
          {
              return IsMatch((Foo)item, this.filterText);
          }
      
          private static bool IsMatch(Foo item, string filterText)
          {
              if (string.IsNullOrEmpty(filterText))
              {
                  return true;
              }
      
              var name = item.Name;
              if (string.IsNullOrEmpty(name))
              {
                  return false;
              }
      
              if (filterText.Length == 1)
              {
                  return name.StartsWith(filterText, StringComparison.OrdinalIgnoreCase);
              }
      
              return name.IndexOf(filterText, 0, StringComparison.OrdinalIgnoreCase) >= 0;
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您将 Dictionary 设置为 itemsource 到列表框,请使用以下代码进行排序,

            private void tb_filter_textChanged(object sender, TextChangedEventArgs e)
            {
                Dictionary<string, string> dictObject = new Dictionary<string, string>();
                ICollectionView view = CollectionViewSource.GetDefaultView(dictObject);
                view.Filter = CustomerFilter;
                listboxname.ItemsSource = view;
            }
        
            private bool CustomerFilter(object item)
            {
                KeyValuePair<string, string> Items = (KeyValuePair<string,string>) item;
                return Items.Value.ToString().Contains("a");
            }
        

        以上代码返回包含“a”的项目。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-07-05
          • 1970-01-01
          • 2019-07-16
          • 2011-03-25
          • 1970-01-01
          • 2021-10-30
          相关资源
          最近更新 更多