【问题标题】:How to use CollectionViewSource to filter ObservableCollection<T> displayed in ListView如何使用 CollectionViewSource 过滤 ListView 中显示的 ObservableCollection<T>
【发布时间】:2020-07-14 08:29:31
【问题描述】:

我见过很多类似的问题,但我找不到一个问题/答案或教程,其中清楚地列出了使其工作所需的所有组件。我正在尝试关注 MVVM,但由于这完全是 UI 问题,我并不反对做一些代码隐藏。

我想要达到的目标:

  • ListView.ItemsSource 绑定到 ObservableCollection&lt;T&gt;
  • 根据TextBox过滤ListView中显示的项目
  • 过滤器更新为TextBox中的用户类型

在我的ViewModel 我有这样的东西:

private ObservableCollection<Customer> _customers;
public ObservableCollection<Customer> Customers
{
    get { return _customers; }
    set
    {
        _customers= value;
        RaisePropertyChanged("Customers");
    }
}

private Customer _selected_Customer;
public Customer Selected_Customer
{
    get { return _selected_Customer; }
    set
    {
        _selected_Customer= value;
        RaisePropertyChanged("Selected_Customer");
    }
}

private string _filtered_Name;
public string Filtered_Name
{
    get { return _filtered_Name; }
    set
    {
        _filtered_Name = value;
        RaisePropertyChanged("Filtered_Name");
    }
}

在我的 XAML 中是这样的:

<CollectionViewSource x:Key="cvs"
                      x:Name="Customer_Details_View"
                      Source="{Binding Path=Customers}"/>

<TextBox x:Name="Filtered_Name" Text="{Binding Filtered_Name, Mode=TwoWay}"/>

<ListView ItemsSource="{Binding ElementName=Customer_Details_View}"
          SelectedItem="{Binding Selected_Customer, Mode=TwoWay}">

我想用以下逻辑过滤我的ObservableCollection&lt;Customer&gt;Customer.Name.ToLower().Contains(Filtered_Name.ToLower())

如何将TextBox.Text 绑定到CollectionViewSource 或利用CollectionViewSource.Filter 事件来应用上述过滤器?

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    您可能希望在 VM 中声明 collectionviewsource 并直接绑定到它。完成后,您可以按照此问题CollectionViewSource, how to filter data?

    中的回答更改过滤器

    VM 示例,不按摩可能无法工作。

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Data;
    
    namespace CollectionViewSourceExample
    {
        class MainWindowViewModel : INotifyPropertyChanged
        {
            private string _filter;
    
            public MainWindowViewModel()
            {
                SourceCollection = new ObservableCollection<string>();
                SourceCollection.Add("Fred Flintstone");
                SourceCollection.Add("Wilma Flintstone");
                SourceCollection.Add("Bambam Flintstone");
                SourceCollection.Add("Barny Rubble");
                SourceCollection.Add("Betty Rubble");
    
                ViewSource = (ListCollectionView)CollectionViewSource.GetDefaultView(SourceCollection);
                ViewSource.Filter = SourceFilter;
                ViewSource.IsLiveFiltering = true;
            }
    
            private bool SourceFilter(object obj)
            {
                string val = (string)obj;
                return string.IsNullOrWhiteSpace(Filter) || val.Contains(Filter);
            }
    
            public string Filter
            {
                get { return _filter; }
                set
                {
                    _filter = value;
                    PropertyChanged(this, new PropertyChangedEventArgs("Filter"));
                    ViewSource.Refresh();
                }
            }
    
            public ObservableCollection<string> SourceCollection { get; }
            public ListCollectionView ViewSource { get; }
    
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
    

    【讨论】:

    • 你能扩展一下吗?如果我在 ViewModel 中声明我的CollectionViewSource,那么过滤会去哪里?肯定会以紧密耦合的 View 和 ViewModel 告终?我也不太明白如何处理链接的答案......与我看过的所有其他人一样,它缺乏关于如何从简单的绑定 ObservableCollection 获得所需结果的全面解释。跨度>
    • 您已经获得了过滤器值的绑定属性。当在 VM 中更改时,过滤器会更新。除了它是一个视图源之外,它与公开一个集合相同。 UI 与 VM 的绑定不再像以前那样紧密。
    • 好的,如果我在我的 VM 中声明类似:public CollectionViewSource Filtered_View { get { return _filtered_View; } set { _filtered_View = value; RaisePropertyChanged("Filtered_View"); } } 我应该如何在 VM 中使用 Filtered_Name 属性?抱歉,我确定我只是有点慢,但我无法理解我需要做的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 2011-07-04
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多