WPF Filter a ListBox

后端 未结 3 1035
耶瑟儿~
耶瑟儿~ 2020-12-02 00:01

I have a ListBox with binding to a list of strings. I want to filter the list when I enter text in a TextBox. How can I do it?

publ         


        
3条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-02 00:17

    Here is an attached property for binding a filter:

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

    Used like this in xaml:

    
        ...
    

    And viewmodel:

    public class ViewModel : INotifyPropertyChanged
    {
        private string filterText;
        private Predicate filter;
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public ObservableCollection Foos { get; } = new ObservableCollection();
    
        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)null : this.IsMatch;
            }
        }
    
        public Predicate 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;
        }
    }
    
        

    提交回复
    热议问题