如何调用Items.Refresh()?

How to call Items.Refresh()?

我正在为一个集合制作过滤器。
我知道如何使用 CollectionViewSource 来做到这一点。
但我想在不使用 CVS 的情况下完成它。
按照我的思路,ItemsControl.Items属性里面有个CollectionView,可以用这个属性.
的方法 可以毫无问题地添加过滤器。
但是在调用 Items.Refresh() 之后没有任何变化。

简单示例:

    <UniformGrid Columns="2">
        <FrameworkElement.Resources>
            <sc:StringCollection
                x:Key="coll">
                <sys:String>112</sys:String>
                <sys:String>22</sys:String>
                <sys:String>33</sys:String>
                <sys:String>114</sys:String>
                <sys:String>411</sys:String>
            </sc:StringCollection>
            <CollectionViewSource
                x:Key="cvs"
                Source="{Binding Mode=OneWay, Source={StaticResource coll}}"
                Filter="OnFilterCV"/>
        </FrameworkElement.Resources>
        <TextBox x:Name="tBox"
                 Text="1"
                 TextChanged="OnTextChanged"
                 VerticalAlignment="Center"/>
        <TextBox x:Name="tBoxCV"
                 Text="1"
                 TextChanged="OnTextChangedCV"
                 VerticalAlignment="Center"/>
        <ItemsControl x:Name="iCtrl"
                      ItemsSource="{Binding Mode=OneWay, Source={StaticResource coll}}">
        </ItemsControl>
        <ItemsControl x:Name="iCtrlCV"
                      ItemsSource="{Binding Mode=OneWay, Source={StaticResource cvs}}">
        </ItemsControl>
    </UniformGrid>
    public partial class MainWindow : Window
    {
        private readonly CollectionViewSource cvs;
        public MainWindow()
        {
            InitializeComponent();
            iCtrl.Items.Filter = OnFilter;
            cvs = (CollectionViewSource)iCtrlCV.FindResource("cvs");
        }

        private bool OnFilter(object obj)
        {
            if (string.IsNullOrWhiteSpace(tBox.Text))
                return true;
            string item = (string)obj;
            return item.Contains(tBox.Text, StringComparison.OrdinalIgnoreCase);
        }

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
            iCtrl?.Items.Refresh();
        }

        private void OnFilterCV(object sender, FilterEventArgs e)
        {
            e.Accepted = string.IsNullOrWhiteSpace(tBoxCV.Text) ||
                ((string)e.Item).Contains(tBoxCV.Text, StringComparison.OrdinalIgnoreCase);
        }

        private void OnTextChangedCV(object sender, TextChangedEventArgs e)
        {
            Debug.WriteLine($"OnTextChangedCV:\"{tBoxCV.Text}\"");
            cvs?.View.Refresh();
        }
    }

我是误会了什么还是做错了什么?

已更新。 解决方案基于@BionicCode 的评论。

        private void OnTextChanged(object sender, TextChangedEventArgs e)
        {
            Debug.WriteLine($"OnTextChanged:\"{tBox.Text}\"");
            //iCtrl?.Items.Refresh();
            if (iCtrl != null)
                iCtrl.Items.Filter = new Predicate<object>(OnFilter);
        }

ItemsControl.Items 的类型为 ItemsCollectionItemsCollection 实现了不同的 Refresh 行为。 Items 属性 基本上供内部使用。如果你必须依赖 CollectionView.Refresh,你应该明确地使用 CollectionView

ItemsControl itemsControl;
itemsControl.Items.Filter = item => (item as string).Contains("A");
CollectionView collectionView = CollectionViewSource.GetDefaultView(itemsControl.ItemsSource);
collectionView.Refresh();