C# 是否在UI上筛选可观察到的收集项?

C# 是否在UI上筛选可观察到的收集项?,c#,wpf,xaml,C#,Wpf,Xaml,我制作了一个应用程序,可以从internet计划一些事件,该事件被插入到列表视图中,该列表将GroupDescription中的内容组织如下: <CollectionViewSource Source="{Binding Matches}" x:Key="GroupedItems"> <CollectionViewSource.GroupDescriptions> <PropertyGroupDescription Prope

我制作了一个应用程序,可以从internet计划一些事件,该事件被插入到
列表视图中
,该列表将
GroupDescription
中的内容组织如下:

<CollectionViewSource Source="{Binding Matches}" x:Key="GroupedItems">
        <CollectionViewSource.GroupDescriptions>
            <PropertyGroupDescription PropertyName="MatchNation" />
            <PropertyGroupDescription PropertyName="MatchLeague" />
        </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

现在,我有了一个
文本框
,用户可以在
匹配项
集合中搜索特定项,我试图实现的是使用用户在
文本框
中提供的给定
搜索
字符串过滤集合

我现在所做的是使用
linq
,创建集合的备份,并删除所有不符合用户
搜索
字符串的项,但我注意到这段代码太重,而且对于实现简单的UI过滤器来说,代码太多

我想知道是否有可能创建类似于xaml的东西。因此,本质上我在xaml中绑定了一个属性,该属性获取由
文本框提供的搜索字符串,当值更改时,
匹配的
集合将被搜索的文本过滤,所有这些都通过xaml完成

这可能吗

示例

中可用的项目与
匹配:

  • 你好
  • 世界
用户在
文本框中搜索
=>您好:


列表视图中
将仅显示
Hello

性能,您可能需要尝试一些方法,只需测量实际结果即可找到最佳答案。但是,我认为在CollectionViewSource上使用
过滤器
回调非常有意义。基本上,您只需将
Filter
属性分配给一个回调,该回调接受来自源的项,并返回一个
bool
,以判断是否应该显示它。下面是一个例子:

// Create a view of your data, the listview should be bound to this too
ICollectionView _matchesView = CollectionViewSource.GetDefaultView(Matches);
// assign the Filter callback to setup filtering
_matchesView.Filter = FilterMatches;

// write the callback method, which returns true for items to display and false for items to hide
private bool MatchFilter(object item)
{
    // you can put any logic you need in here
    var match = item as string;
    return match.Contains(_searchQuery);
}
如果源集合或搜索查询发生更改,则还需要更新集合视图源。例如,如果您有一个
FilterString
属性,该属性绑定到用户输入搜索词的位置,您可以在setter中执行类似操作。关键是当某些内容发生更改时,需要调用
Refresh()

public string FilterString
{
    get { return _filterString; }
    set
    {
        _filterString = value;
        NotifyPropertyChanged(nameof(FilterString));
        _matchesView.Refresh();
    }
}

主要的变化是您的
ListView
需要绑定到集合视图源,以利用该对象中内置的过滤功能。否则,如果listview仍然绑定到实际集合,则不会对其进行筛选。您可以将视图源作为视图模型中的一个属性或视图的代码隐藏。

对于性能,您可能需要尝试一些方法,只需测量实际结果即可找到最佳答案。但是,我认为在CollectionViewSource上使用
过滤器
回调非常有意义。基本上,您只需将
Filter
属性分配给一个回调,该回调接受来自源的项,并返回一个
bool
,以判断是否应该显示它。下面是一个例子:

// Create a view of your data, the listview should be bound to this too
ICollectionView _matchesView = CollectionViewSource.GetDefaultView(Matches);
// assign the Filter callback to setup filtering
_matchesView.Filter = FilterMatches;

// write the callback method, which returns true for items to display and false for items to hide
private bool MatchFilter(object item)
{
    // you can put any logic you need in here
    var match = item as string;
    return match.Contains(_searchQuery);
}
如果源集合或搜索查询发生更改,则还需要更新集合视图源。例如,如果您有一个
FilterString
属性,该属性绑定到用户输入搜索词的位置,您可以在setter中执行类似操作。关键是当某些内容发生更改时,需要调用
Refresh()

public string FilterString
{
    get { return _filterString; }
    set
    {
        _filterString = value;
        NotifyPropertyChanged(nameof(FilterString));
        _matchesView.Refresh();
    }
}

主要的变化是您的
ListView
需要绑定到集合视图源,以利用该对象中内置的过滤功能。否则,如果listview仍然绑定到实际集合,则不会对其进行筛选。您可以将视图源作为视图模型中的属性或视图的代码隐藏。

如果使用.GetDefaultView,我必须将ObservableCollection声明为静态。为什么?您不需要将其设置为静态。它应该是这样的:
ObservableCollection\u matches=newobservableCollection();var cvs=CollectionViewSource.GetDefaultView(_匹配);cvs.Filter=…
GetDefaultView()方法是静态的,但是您可以向它传递一个非静态参数。好的,到.Filter我需要像您的示例中那样传递属性
FilterString
?Filter需要用于回调的方法。在这个示例中,我定义了一个名为
MatchFilter
的方法,该方法接受一个项并返回true/false以确定是否应该显示该项,因此我将方法名MatchFilter传递给.Filter属性。您将定义一个类似的方法,这就是您应该分配给Filter属性的方法。这是一个很好的例子,我发现有人展示了如何使用这种方法来解决一个与你非常相似的问题,也许这将有助于澄清它。如果我使用.GetDefaultView,我必须将ObservableCollection声明为静态,为什么?不需要将其设置为静态。它应该是这样的:
ObservableCollection\u matches=newobservableCollection();var cvs=CollectionViewSource.GetDefaultView(_匹配);cvs.Filter=…
GetDefaultView()方法是静态的,但是您可以向它传递一个非静态参数。好的,到.Filter我需要像您的示例中那样传递属性
FilterString
?Filter需要用于回调的方法。在这个示例中,我定义了一个名为
MatchFilter
的方法,该方法接受一个项并返回true/false以确定是否应该显示该项,因此我将方法名MatchFilter传递给.Filter属性。您将定义一个类似的方法,这就是您应该分配给Filter属性的方法。这是一个很好的例子,我发现有人展示了如何使用这种方法来解决一个与你非常相似的问题,也许这将有助于澄清它。